[automerger skipped] DO NOT MERGE Separate SDP procedure from bonding state (2/2) am: 30e2e54327
am: 2d6b83c629 -s ours
am skip reason: change_id Ifefb749e0274ae018714340654287a0412b59b89 with SHA1 55d82d63b7 is in history
Change-Id: I604b8f1077c6a9a3aae4488a5f2180a13a1cf913
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..726a790
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,3 @@
+subdirs = [
+ "jni",
+]
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 379440d..a086284 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -210,7 +210,8 @@
android:label=""
android:excludeFromRecents="true"
android:configChanges="orientation|keyboardHidden"
- android:enabled="@bool/profile_supported_opp">
+ android:enabled="@bool/profile_supported_opp"
+ android:theme="@android:style/Theme.DeviceDefault.Settings">
<intent-filter>
<action android:name="com.android.bluetooth.action.TransferHistory" />
<category android:name="android.intent.category.DEFAULT" />
diff --git a/jni/Android.bp b/jni/Android.bp
new file mode 100644
index 0000000..73700e8
--- /dev/null
+++ b/jni/Android.bp
@@ -0,0 +1,39 @@
+cc_library_shared {
+ name: "libbluetooth_jni",
+ srcs: [
+ "com_android_bluetooth_btservice_AdapterService.cpp",
+ "com_android_bluetooth_hfp.cpp",
+ "com_android_bluetooth_hfpclient.cpp",
+ "com_android_bluetooth_a2dp.cpp",
+ "com_android_bluetooth_a2dp_sink.cpp",
+ "com_android_bluetooth_avrcp.cpp",
+ "com_android_bluetooth_avrcp_controller.cpp",
+ "com_android_bluetooth_hid.cpp",
+ "com_android_bluetooth_hidd.cpp",
+ "com_android_bluetooth_hdp.cpp",
+ "com_android_bluetooth_pan.cpp",
+ "com_android_bluetooth_gatt.cpp",
+ "com_android_bluetooth_sdp.cpp",
+ ],
+ include_dirs: [
+ "libnativehelper/include/nativehelper",
+ "system/bt/types",
+ ],
+ shared_libs: [
+ "libandroid_runtime",
+ "libchrome",
+ "libnativehelper",
+ "libcutils",
+ "libutils",
+ "liblog",
+ "libhardware",
+ ],
+ static_libs: [
+ "libbluetooth-types",
+ ],
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Wno-unused-parameter",
+ ],
+}
diff --git a/jni/Android.mk b/jni/Android.mk
deleted file mode 100644
index 971b614..0000000
--- a/jni/Android.mk
+++ /dev/null
@@ -1,37 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- com_android_bluetooth_btservice_AdapterService.cpp \
- com_android_bluetooth_hfp.cpp \
- com_android_bluetooth_hfpclient.cpp \
- com_android_bluetooth_a2dp.cpp \
- com_android_bluetooth_a2dp_sink.cpp \
- com_android_bluetooth_avrcp.cpp \
- com_android_bluetooth_avrcp_controller.cpp \
- com_android_bluetooth_hid.cpp \
- com_android_bluetooth_hidd.cpp \
- com_android_bluetooth_hdp.cpp \
- com_android_bluetooth_pan.cpp \
- com_android_bluetooth_gatt.cpp \
- com_android_bluetooth_sdp.cpp
-
-LOCAL_C_INCLUDES += \
- $(JNI_H_INCLUDE) \
-
-LOCAL_SHARED_LIBRARIES := \
- libandroid_runtime \
- libchrome \
- libnativehelper \
- libcutils \
- libutils \
- liblog \
- libhardware
-
-LOCAL_CFLAGS += -Wall -Wextra -Wno-unused-parameter
-
-LOCAL_MODULE := libbluetooth_jni
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/jni/com_android_bluetooth_a2dp.cpp b/jni/com_android_bluetooth_a2dp.cpp
index a2928ff..26c9359 100644
--- a/jni/com_android_bluetooth_a2dp.cpp
+++ b/jni/com_android_bluetooth_a2dp.cpp
@@ -48,38 +48,38 @@
static jobject mCallbacksObj = NULL;
static void bta2dp_connection_state_callback(btav_connection_state_t state,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
ALOGI("%s", __func__);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for connection state");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged,
(jint)state, addr.get());
}
static void bta2dp_audio_state_callback(btav_audio_state_t state,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
ALOGI("%s", __func__);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for connection state");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged,
(jint)state, addr.get());
@@ -319,7 +319,7 @@
return JNI_FALSE;
}
- bt_status_t status = sBluetoothA2dpInterface->connect((bt_bdaddr_t*)addr);
+ bt_status_t status = sBluetoothA2dpInterface->connect((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed HF connection, status: %d", status);
}
@@ -337,7 +337,7 @@
return JNI_FALSE;
}
- bt_status_t status = sBluetoothA2dpInterface->disconnect((bt_bdaddr_t*)addr);
+ bt_status_t status = sBluetoothA2dpInterface->disconnect((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed HF disconnection, status: %d", status);
}
diff --git a/jni/com_android_bluetooth_a2dp_sink.cpp b/jni/com_android_bluetooth_a2dp_sink.cpp
index 185fc69..989cd6f 100644
--- a/jni/com_android_bluetooth_a2dp_sink.cpp
+++ b/jni/com_android_bluetooth_a2dp_sink.cpp
@@ -34,44 +34,44 @@
static jobject mCallbacksObj = NULL;
static void bta2dp_connection_state_callback(btav_connection_state_t state,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
ALOGI("%s", __func__);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for connection state");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged,
(jint)state, addr.get());
}
static void bta2dp_audio_state_callback(btav_audio_state_t state,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
ALOGI("%s", __func__);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for connection state");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged,
(jint)state, addr.get());
}
-static void bta2dp_audio_config_callback(bt_bdaddr_t* bd_addr,
+static void bta2dp_audio_config_callback(RawAddress* bd_addr,
uint32_t sample_rate,
uint8_t channel_count) {
ALOGI("%s", __func__);
@@ -79,13 +79,13 @@
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for connection state");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioConfigChanged,
addr.get(), (jint)sample_rate,
@@ -177,7 +177,7 @@
return JNI_FALSE;
}
- bt_status_t status = sBluetoothA2dpInterface->connect((bt_bdaddr_t*)addr);
+ bt_status_t status = sBluetoothA2dpInterface->connect((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed HF connection, status: %d", status);
}
@@ -195,7 +195,7 @@
return JNI_FALSE;
}
- bt_status_t status = sBluetoothA2dpInterface->disconnect((bt_bdaddr_t*)addr);
+ bt_status_t status = sBluetoothA2dpInterface->disconnect((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed HF disconnection, status: %d", status);
}
diff --git a/jni/com_android_bluetooth_avrcp.cpp b/jni/com_android_bluetooth_avrcp.cpp
index 5647705..d365b53 100644
--- a/jni/com_android_bluetooth_avrcp.cpp
+++ b/jni/com_android_bluetooth_avrcp.cpp
@@ -57,7 +57,7 @@
static void cleanup_items(btrc_folder_items_t* p_items, int numItems);
-static void btavrcp_remote_features_callback(bt_bdaddr_t* bd_addr,
+static void btavrcp_remote_features_callback(RawAddress* bd_addr,
btrc_remote_features_t features) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -68,20 +68,20 @@
}
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Unable to allocate byte array for bd_addr");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getRcFeatures, addr.get(),
(jint)features);
}
/** Callback for play status request */
-static void btavrcp_get_play_status_callback(bt_bdaddr_t* bd_addr) {
+static void btavrcp_get_play_status_callback(RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -91,20 +91,20 @@
}
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for get_play_status command");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getPlayStatus, addr.get());
}
static void btavrcp_get_element_attr_callback(uint8_t num_attr,
btrc_media_attr_t* p_attrs,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -114,7 +114,7 @@
}
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for get_element_attr command");
return;
@@ -129,7 +129,7 @@
sCallbackEnv->SetIntArrayRegion(attrs.get(), 0, num_attr, (jint*)p_attrs);
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getElementAttr, addr.get(),
(jbyte)num_attr, attrs.get());
@@ -137,7 +137,7 @@
static void btavrcp_register_notification_callback(btrc_event_id_t event_id,
uint32_t param,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -147,20 +147,20 @@
}
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for register_notification command");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_registerNotification,
addr.get(), (jint)event_id, (jint)param);
}
static void btavrcp_volume_change_callback(uint8_t volume, uint8_t ctype,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -170,13 +170,13 @@
}
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for volume_change command");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_volumeChangeCallback,
@@ -184,7 +184,7 @@
}
static void btavrcp_passthrough_command_callback(int id, int pressed,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -194,12 +194,12 @@
}
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for passthrough_command command");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handlePassthroughCmd,
@@ -207,7 +207,7 @@
}
static void btavrcp_set_addressed_player_callback(uint16_t player_id,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -217,20 +217,20 @@
}
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for set_addressed_player command");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_setAddressedPlayerCallback,
addr.get(), (jint)player_id);
}
static void btavrcp_set_browsed_player_callback(uint16_t player_id,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
if (!mCallbacksObj) {
@@ -239,12 +239,12 @@
}
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for set_browsed_player command");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_setBrowsedPlayerCallback,
@@ -253,7 +253,7 @@
static void btavrcp_get_folder_items_callback(
uint8_t scope, uint32_t start_item, uint32_t end_item, uint8_t num_attr,
- uint32_t* p_attr_ids, bt_bdaddr_t* bd_addr) {
+ uint32_t* p_attr_ids, RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -263,7 +263,7 @@
}
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for get_folder_items command");
return;
@@ -271,7 +271,7 @@
uint32_t* puiAttr = (uint32_t*)p_attr_ids;
ScopedLocalRef<jintArray> attr_ids(sCallbackEnv.get(), NULL);
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
/* check number of attributes requested by remote device */
@@ -293,7 +293,7 @@
}
static void btavrcp_change_path_callback(uint8_t direction, uint8_t* folder_uid,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -310,13 +310,13 @@
}
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for change_path command");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->SetByteArrayRegion(
attrs.get(), 0, sizeof(uint8_t) * BTRC_UID_SIZE, (jbyte*)folder_uid);
@@ -328,7 +328,7 @@
uint16_t uid_counter,
uint8_t num_attr,
btrc_media_attr_t* p_attrs,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -345,7 +345,7 @@
}
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for get_item_attr command");
return;
@@ -358,7 +358,7 @@
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->SetIntArrayRegion(attrs.get(), 0, num_attr, (jint*)p_attrs);
sCallbackEnv->SetByteArrayRegion(
@@ -370,7 +370,7 @@
}
static void btavrcp_play_item_callback(uint8_t scope, uint16_t uid_counter,
- uint8_t* uid, bt_bdaddr_t* bd_addr) {
+ uint8_t* uid, RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
if (!mCallbacksObj) {
@@ -386,13 +386,13 @@
}
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for play_item command");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->SetByteArrayRegion(
attrs.get(), 0, sizeof(uint8_t) * BTRC_UID_SIZE, (jbyte*)uid);
@@ -402,7 +402,7 @@
}
static void btavrcp_get_total_num_items_callback(uint8_t scope,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
if (!mCallbacksObj) {
@@ -411,20 +411,20 @@
}
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for get_total_num_items command");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getTotalNumOfItemsCallback,
addr.get(), (jbyte)scope);
}
static void btavrcp_search_callback(uint16_t charset_id, uint16_t str_len,
- uint8_t* p_str, bt_bdaddr_t* bd_addr) {
+ uint8_t* p_str, RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
if (!mCallbacksObj) {
@@ -440,13 +440,13 @@
}
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for search command");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->SetByteArrayRegion(attrs.get(), 0, str_len * sizeof(uint8_t),
(jbyte*)p_str);
@@ -456,7 +456,7 @@
static void btavrcp_add_to_play_list_callback(uint8_t scope, uint8_t* uid,
uint16_t uid_counter,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
if (!mCallbacksObj) {
@@ -465,7 +465,7 @@
}
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for add_to_play_list command");
return;
@@ -478,7 +478,7 @@
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->SetByteArrayRegion(
attrs.get(), 0, sizeof(uint8_t) * BTRC_UID_SIZE, (jbyte*)uid);
@@ -630,7 +630,7 @@
}
bt_status_t status = sBluetoothAvrcpInterface->get_play_status_rsp(
- (bt_bdaddr_t*)addr, (btrc_play_status_t)playStatus, songLen, songPos);
+ (RawAddress*)addr, (btrc_play_status_t)playStatus, songLen, songPos);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed get_play_status_rsp, status: %d", status);
}
@@ -692,7 +692,7 @@
return JNI_FALSE;
}
- bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
+ RawAddress* btAddr = (RawAddress*)addr;
bt_status_t status =
sBluetoothAvrcpInterface->get_element_attr_rsp(btAddr, numAttr, pAttrs);
if (status != BT_STATUS_SUCCESS) {
@@ -756,7 +756,7 @@
}
}
- bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
+ RawAddress* btAddr = (RawAddress*)addr;
bt_status_t status = sBluetoothAvrcpInterface->get_item_attr_rsp(
btAddr, (btrc_status_t)rspStatus, numAttr, pAttrs);
if (status != BT_STATUS_SUCCESS)
@@ -1022,7 +1022,7 @@
}
}
- bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
+ RawAddress* btAddr = (RawAddress*)addr;
bt_status_t status = sBluetoothAvrcpInterface->get_folder_items_list_rsp(
btAddr, (btrc_status_t)rspStatus, uidCounter, numItems, p_items);
if (status != BT_STATUS_SUCCESS) {
@@ -1157,7 +1157,7 @@
}
}
- bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
+ RawAddress* btAddr = (RawAddress*)addr;
bt_status_t status = sBluetoothAvrcpInterface->get_folder_items_list_rsp(
btAddr, (btrc_status_t)rspStatus, uidCounter, numItems, p_items);
if (status != BT_STATUS_SUCCESS)
@@ -1195,7 +1195,7 @@
return JNI_FALSE;
}
- bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
+ RawAddress* btAddr = (RawAddress*)addr;
bt_status_t status = sBluetoothAvrcpInterface->set_addressed_player_rsp(
btAddr, (btrc_status_t)rspStatus);
if (status != BT_STATUS_SUCCESS) {
@@ -1249,7 +1249,7 @@
uint8_t folder_depth =
depth; /* folder_depth is 0 if current folder is root */
uint16_t charset_id = BTRC_CHARSET_ID_UTF8;
- bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
+ RawAddress* btAddr = (RawAddress*)addr;
bt_status_t status = sBluetoothAvrcpInterface->set_browsed_player_rsp(
btAddr, (btrc_status_t)rspStatus, numItems, charset_id, folder_depth,
p_folders);
@@ -1280,7 +1280,7 @@
}
uint32_t nItems = (uint32_t)numItems;
- bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
+ RawAddress* btAddr = (RawAddress*)addr;
bt_status_t status = sBluetoothAvrcpInterface->change_path_rsp(
btAddr, (btrc_status_t)rspStatus, (uint32_t)nItems);
if (status != BT_STATUS_SUCCESS) {
@@ -1306,7 +1306,7 @@
}
uint32_t nItems = (uint32_t)numItems;
- bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
+ RawAddress* btAddr = (RawAddress*)addr;
bt_status_t status = sBluetoothAvrcpInterface->search_rsp(
btAddr, (btrc_status_t)rspStatus, (uint32_t)uidCounter, (uint32_t)nItems);
if (status != BT_STATUS_SUCCESS) {
@@ -1331,7 +1331,7 @@
return JNI_FALSE;
}
- bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
+ RawAddress* btAddr = (RawAddress*)addr;
bt_status_t status =
sBluetoothAvrcpInterface->play_item_rsp(btAddr, (btrc_status_t)rspStatus);
if (status != BT_STATUS_SUCCESS) {
@@ -1357,7 +1357,7 @@
}
uint32_t nItems = (uint32_t)numItems;
- bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
+ RawAddress* btAddr = (RawAddress*)addr;
bt_status_t status = sBluetoothAvrcpInterface->get_total_num_of_items_rsp(
btAddr, (btrc_status_t)rspStatus, (uint32_t)uidCounter, (uint32_t)nItems);
if (status != BT_STATUS_SUCCESS) {
@@ -1381,7 +1381,7 @@
return JNI_FALSE;
}
- bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
+ RawAddress* btAddr = (RawAddress*)addr;
bt_status_t status = sBluetoothAvrcpInterface->add_to_now_playing_rsp(
btAddr, (btrc_status_t)rspStatus);
if (status != BT_STATUS_SUCCESS) {
diff --git a/jni/com_android_bluetooth_avrcp_controller.cpp b/jni/com_android_bluetooth_avrcp_controller.cpp
index cd2f888..40982ee 100644
--- a/jni/com_android_bluetooth_avrcp_controller.cpp
+++ b/jni/com_android_bluetooth_avrcp_controller.cpp
@@ -53,20 +53,20 @@
static const btrc_ctrl_interface_t* sBluetoothAvrcpInterface = NULL;
static jobject sCallbacksObj = NULL;
-static void btavrcp_passthrough_response_callback(bt_bdaddr_t* bd_addr, int id,
+static void btavrcp_passthrough_response_callback(RawAddress* bd_addr, int id,
int pressed) {
ALOGI("%s: id: %d, pressed: %d", __func__, id, pressed);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for passthrough response");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handlePassthroughRsp,
(jint)id, (jint)pressed, addr.get());
@@ -82,77 +82,76 @@
}
static void btavrcp_connection_state_callback(bool rc_connect, bool br_connect,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
ALOGI("%s: conn state: rc: %d br: %d", __func__, rc_connect, br_connect);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for connection state");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_onConnectionStateChanged,
(jboolean)rc_connect, (jboolean)br_connect,
addr.get());
}
-static void btavrcp_get_rcfeatures_callback(bt_bdaddr_t* bd_addr,
- int features) {
+static void btavrcp_get_rcfeatures_callback(RawAddress* bd_addr, int features) {
ALOGV("%s", __func__);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr ");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_getRcFeatures, addr.get(),
(jint)features);
}
static void btavrcp_setplayerapplicationsetting_rsp_callback(
- bt_bdaddr_t* bd_addr, uint8_t accepted) {
+ RawAddress* bd_addr, uint8_t accepted) {
ALOGV("%s", __func__);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr ");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_setplayerappsettingrsp,
addr.get(), (jint)accepted);
}
static void btavrcp_playerapplicationsetting_callback(
- bt_bdaddr_t* bd_addr, uint8_t num_attr, btrc_player_app_attr_t* app_attrs,
+ RawAddress* bd_addr, uint8_t num_attr, btrc_player_app_attr_t* app_attrs,
uint8_t num_ext_attr, btrc_player_app_ext_attr_t* ext_attrs) {
ALOGI("%s", __func__);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr ");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
/* TODO ext attrs
* Flattening defined attributes: <id,num_values,values[]>
@@ -188,18 +187,18 @@
}
static void btavrcp_playerapplicationsetting_changed_callback(
- bt_bdaddr_t* bd_addr, btrc_player_settings_t* p_vals) {
+ RawAddress* bd_addr, btrc_player_settings_t* p_vals) {
ALOGI("%s", __func__);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to get new array ");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
int arraylen = p_vals->num_attr * 2;
@@ -225,46 +224,46 @@
playerattribs.get(), (jint)arraylen);
}
-static void btavrcp_set_abs_vol_cmd_callback(bt_bdaddr_t* bd_addr,
+static void btavrcp_set_abs_vol_cmd_callback(RawAddress* bd_addr,
uint8_t abs_vol, uint8_t label) {
ALOGI("%s", __func__);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to get new array ");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleSetAbsVolume,
addr.get(), (jbyte)abs_vol, (jbyte)label);
}
-static void btavrcp_register_notification_absvol_callback(bt_bdaddr_t* bd_addr,
+static void btavrcp_register_notification_absvol_callback(RawAddress* bd_addr,
uint8_t label) {
ALOGI("%s", __func__);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to get new array ");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(sCallbacksObj,
method_handleRegisterNotificationAbsVol,
addr.get(), (jbyte)label);
}
-static void btavrcp_track_changed_callback(bt_bdaddr_t* bd_addr,
+static void btavrcp_track_changed_callback(RawAddress* bd_addr,
uint8_t num_attr,
btrc_element_attr_val_t* p_attrs) {
/*
@@ -276,7 +275,7 @@
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to get new array ");
return;
@@ -288,7 +287,7 @@
ALOGE(" failed to set new array for attribIds");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
jclass strclazz = sCallbackEnv->FindClass("java/lang/String");
@@ -318,7 +317,7 @@
stringArray.get());
}
-static void btavrcp_play_position_changed_callback(bt_bdaddr_t* bd_addr,
+static void btavrcp_play_position_changed_callback(RawAddress* bd_addr,
uint32_t song_len,
uint32_t song_pos) {
ALOGI("%s", __func__);
@@ -326,37 +325,37 @@
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to get new array ");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleplaypositionchanged,
addr.get(), (jint)(song_len), (jint)song_pos);
}
static void btavrcp_play_status_changed_callback(
- bt_bdaddr_t* bd_addr, btrc_play_status_t play_status) {
+ RawAddress* bd_addr, btrc_play_status_t play_status) {
ALOGI("%s", __func__);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to get new array ");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleplaystatuschanged,
addr.get(), (jbyte)play_status);
}
static void btavrcp_get_folder_items_callback(
- bt_bdaddr_t* bd_addr, btrc_status_t status,
+ RawAddress* bd_addr, btrc_status_t status,
const btrc_folder_items_t* folder_items, uint8_t count) {
/* Folder items are list of items that can be either BTRC_ITEM_PLAYER
* BTRC_ITEM_MEDIA, BTRC_ITEM_FOLDER. Here we translate them to their java
@@ -546,7 +545,7 @@
}
}
-static void btavrcp_change_path_callback(bt_bdaddr_t* bd_addr, uint8_t count) {
+static void btavrcp_change_path_callback(RawAddress* bd_addr, uint8_t count) {
ALOGI("%s count %d", __func__, count);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -555,7 +554,7 @@
(jint)count);
}
-static void btavrcp_set_browsed_player_callback(bt_bdaddr_t* bd_addr,
+static void btavrcp_set_browsed_player_callback(RawAddress* bd_addr,
uint8_t num_items,
uint8_t depth) {
ALOGI("%s items %d depth %d", __func__, num_items, depth);
@@ -566,7 +565,7 @@
(jint)num_items, (jint)depth);
}
-static void btavrcp_set_addressed_player_callback(bt_bdaddr_t* bd_addr,
+static void btavrcp_set_addressed_player_callback(RawAddress* bd_addr,
uint8_t status) {
ALOGI("%s status %d", __func__, status);
@@ -740,7 +739,7 @@
}
bt_status_t status = sBluetoothAvrcpInterface->send_pass_through_cmd(
- (bt_bdaddr_t*)addr, (uint8_t)key_code, (uint8_t)key_state);
+ (RawAddress*)addr, (uint8_t)key_code, (uint8_t)key_state);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed sending passthru command, status: %d", status);
}
@@ -766,7 +765,7 @@
}
bt_status_t status = sBluetoothAvrcpInterface->send_group_navigation_cmd(
- (bt_bdaddr_t*)addr, (uint8_t)key_code, (uint8_t)key_state);
+ (RawAddress*)addr, (uint8_t)key_code, (uint8_t)key_state);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed sending Grp Navigation command, status: %d", status);
}
@@ -813,7 +812,7 @@
}
bt_status_t status = sBluetoothAvrcpInterface->set_player_app_setting_cmd(
- (bt_bdaddr_t*)addr, (uint8_t)num_attrib, pAttrs, pAttrsVal);
+ (RawAddress*)addr, (uint8_t)num_attrib, pAttrs, pAttrsVal);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed sending setPlAppSettValNative command, status: %d", status);
}
@@ -836,7 +835,7 @@
ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
bt_status_t status = sBluetoothAvrcpInterface->set_volume_rsp(
- (bt_bdaddr_t*)addr, (uint8_t)abs_vol, (uint8_t)label);
+ (RawAddress*)addr, (uint8_t)abs_vol, (uint8_t)label);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed sending sendAbsVolRspNative command, status: %d", status);
}
@@ -855,7 +854,7 @@
}
ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
bt_status_t status = sBluetoothAvrcpInterface->register_abs_vol_rsp(
- (bt_bdaddr_t*)addr, (btrc_notification_type_t)rsp_type, (uint8_t)abs_vol,
+ (RawAddress*)addr, (btrc_notification_type_t)rsp_type, (uint8_t)abs_vol,
(uint8_t)label);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed sending sendRegisterAbsVolRspNative command, status: %d",
@@ -875,7 +874,7 @@
}
ALOGV("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
bt_status_t status =
- sBluetoothAvrcpInterface->get_playback_state_cmd((bt_bdaddr_t*)addr);
+ sBluetoothAvrcpInterface->get_playback_state_cmd((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed sending getPlaybackStateNative command, status: %d", status);
}
@@ -893,7 +892,7 @@
}
ALOGV("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
bt_status_t status = sBluetoothAvrcpInterface->get_now_playing_list_cmd(
- (bt_bdaddr_t*)addr, (uint8_t)start, (uint8_t)items);
+ (RawAddress*)addr, (uint8_t)start, (uint8_t)items);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed sending getNowPlayingListNative command, status: %d", status);
}
@@ -910,7 +909,7 @@
}
ALOGV("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
bt_status_t status = sBluetoothAvrcpInterface->get_folder_list_cmd(
- (bt_bdaddr_t*)addr, (uint8_t)start, (uint8_t)items);
+ (RawAddress*)addr, (uint8_t)start, (uint8_t)items);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed sending getFolderListNative command, status: %d", status);
}
@@ -928,7 +927,7 @@
ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
bt_status_t status = sBluetoothAvrcpInterface->get_player_list_cmd(
- (bt_bdaddr_t*)addr, (uint8_t)start, (uint8_t)items);
+ (RawAddress*)addr, (uint8_t)start, (uint8_t)items);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed sending getPlayerListNative command, status: %d", status);
}
@@ -954,7 +953,7 @@
ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
bt_status_t status = sBluetoothAvrcpInterface->change_folder_path_cmd(
- (bt_bdaddr_t*)addr, (uint8_t)direction, (uint8_t*)uid);
+ (RawAddress*)addr, (uint8_t)direction, (uint8_t*)uid);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed sending changeFolderPathNative command, status: %d", status);
}
@@ -972,7 +971,7 @@
ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
bt_status_t status = sBluetoothAvrcpInterface->set_browsed_player_cmd(
- (bt_bdaddr_t*)addr, (uint16_t)id);
+ (RawAddress*)addr, (uint16_t)id);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed sending setBrowsedPlayerNative command, status: %d", status);
}
@@ -990,7 +989,7 @@
ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
bt_status_t status = sBluetoothAvrcpInterface->set_addressed_player_cmd(
- (bt_bdaddr_t*)addr, (uint16_t)id);
+ (RawAddress*)addr, (uint16_t)id);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed sending setAddressedPlayerNative command, status: %d",
status);
@@ -1015,7 +1014,7 @@
ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
bt_status_t status = sBluetoothAvrcpInterface->play_item_cmd(
- (bt_bdaddr_t*)addr, (uint8_t)scope, (uint8_t*)uid, (uint16_t)uidCounter);
+ (RawAddress*)addr, (uint8_t)scope, (uint8_t*)uid, (uint16_t)uidCounter);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed sending playItemNative command, status: %d", status);
}
diff --git a/jni/com_android_bluetooth_btservice_AdapterService.cpp b/jni/com_android_bluetooth_btservice_AdapterService.cpp
index f743ec5..dc2e07a 100644
--- a/jni/com_android_bluetooth_btservice_AdapterService.cpp
+++ b/jni/com_android_bluetooth_btservice_AdapterService.cpp
@@ -148,7 +148,7 @@
}
static void remote_device_properties_callback(bt_status_t status,
- bt_bdaddr_t* bd_addr,
+ RawAddress* bd_addr,
int num_properties,
bt_property_t* properties) {
CallbackEnv sCallbackEnv(__func__);
@@ -191,13 +191,13 @@
}
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Error while allocation byte array in %s", __func__);
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
jintArray typesPtr = types.get();
@@ -239,15 +239,14 @@
(const char*)properties[addr_index].val);
remote_device_properties_callback(BT_STATUS_SUCCESS,
- (bt_bdaddr_t*)properties[addr_index].val,
+ (RawAddress*)properties[addr_index].val,
num_properties, properties);
sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback,
addr.get());
}
-static void bond_state_changed_callback(bt_status_t status,
- bt_bdaddr_t* bd_addr,
+static void bond_state_changed_callback(bt_status_t status, RawAddress* bd_addr,
bt_bond_state_t state) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -258,19 +257,19 @@
}
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Address allocation failed in %s", __func__);
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback,
(jint)status, addr.get(), (jint)state);
}
-static void acl_state_changed_callback(bt_status_t status, bt_bdaddr_t* bd_addr,
+static void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr,
bt_acl_state_t state) {
if (!bd_addr) {
ALOGE("Address is null in %s", __func__);
@@ -281,12 +280,12 @@
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Address allocation failed in %s", __func__);
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_aclStateChangeCallback,
@@ -303,7 +302,7 @@
sJniCallbacksObj, method_discoveryStateChangeCallback, (jint)state);
}
-static void pin_request_callback(bt_bdaddr_t* bd_addr, bt_bdname_t* bdname,
+static void pin_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname,
uint32_t cod, bool min_16_digits) {
if (!bd_addr) {
ALOGE("Address is null in %s", __func__);
@@ -314,13 +313,13 @@
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Error while allocating in: %s", __func__);
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
ScopedLocalRef<jbyteArray> devname(
@@ -337,7 +336,7 @@
addr.get(), devname.get(), cod, min_16_digits);
}
-static void ssp_request_callback(bt_bdaddr_t* bd_addr, bt_bdname_t* bdname,
+static void ssp_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname,
uint32_t cod, bt_ssp_variant_t pairing_variant,
uint32_t pass_key) {
if (!bd_addr) {
@@ -348,13 +347,13 @@
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Error while allocating in: %s", __func__);
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
ScopedLocalRef<jbyteArray> devname(
@@ -751,7 +750,7 @@
return JNI_FALSE;
}
- int ret = sBluetoothInterface->create_bond((bt_bdaddr_t*)addr, transport);
+ int ret = sBluetoothInterface->create_bond((RawAddress*)addr, transport);
env->ReleaseByteArrayElements(address, addr, 0);
return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}
@@ -848,7 +847,7 @@
memcpy(oob_data.le_sc_r, leScRBytes, len);
}
- status = sBluetoothInterface->create_bond_out_of_band((bt_bdaddr_t*)addr,
+ status = sBluetoothInterface->create_bond_out_of_band((RawAddress*)addr,
transport, &oob_data);
done:
@@ -877,7 +876,7 @@
return JNI_FALSE;
}
- int ret = sBluetoothInterface->remove_bond((bt_bdaddr_t*)addr);
+ int ret = sBluetoothInterface->remove_bond((RawAddress*)addr);
env->ReleaseByteArrayElements(address, addr, 0);
return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
@@ -894,7 +893,7 @@
return JNI_FALSE;
}
- int ret = sBluetoothInterface->cancel_bond((bt_bdaddr_t*)addr);
+ int ret = sBluetoothInterface->cancel_bond((RawAddress*)addr);
env->ReleaseByteArrayElements(address, addr, 0);
return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}
@@ -910,7 +909,7 @@
return JNI_FALSE;
}
- int ret = sBluetoothInterface->get_connection_state((bt_bdaddr_t*)addr);
+ int ret = sBluetoothInterface->get_connection_state((RawAddress*)addr);
env->ReleaseByteArrayElements(address, addr, 0);
return ret;
@@ -938,7 +937,7 @@
}
}
- int ret = sBluetoothInterface->pin_reply((bt_bdaddr_t*)addr, accept, len,
+ int ret = sBluetoothInterface->pin_reply((RawAddress*)addr, accept, len,
(bt_pin_code_t*)pinPtr);
env->ReleaseByteArrayElements(address, addr, 0);
env->ReleaseByteArrayElements(pinArray, pinPtr, 0);
@@ -959,7 +958,7 @@
}
int ret = sBluetoothInterface->ssp_reply(
- (bt_bdaddr_t*)addr, (bt_ssp_variant_t)type, accept, passkey);
+ (RawAddress*)addr, (bt_ssp_variant_t)type, accept, passkey);
env->ReleaseByteArrayElements(address, addr, 0);
return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
@@ -1014,7 +1013,7 @@
}
int ret = sBluetoothInterface->get_remote_device_property(
- (bt_bdaddr_t*)addr, (bt_property_type_t)type);
+ (RawAddress*)addr, (bt_property_type_t)type);
env->ReleaseByteArrayElements(address, addr, 0);
return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}
@@ -1044,8 +1043,8 @@
prop.len = env->GetArrayLength(value);
prop.val = val;
- int ret = sBluetoothInterface->set_remote_device_property((bt_bdaddr_t*)addr,
- &prop);
+ int ret =
+ sBluetoothInterface->set_remote_device_property((RawAddress*)addr, &prop);
env->ReleaseByteArrayElements(value, val, 0);
env->ReleaseByteArrayElements(address, addr, 0);
@@ -1064,7 +1063,7 @@
return JNI_FALSE;
}
- int ret = sBluetoothInterface->get_remote_services((bt_bdaddr_t*)addr);
+ int ret = sBluetoothInterface->get_remote_services((RawAddress*)addr);
env->ReleaseByteArrayElements(address, addr, 0);
return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}
@@ -1092,7 +1091,7 @@
int socket_fd = -1;
bt_status_t status = sBluetoothSocketInterface->connect(
- (bt_bdaddr_t*)addr, (btsock_type_t)type, (const uint8_t*)uuid, channel,
+ (RawAddress*)addr, (btsock_type_t)type, (const uint8_t*)uuid, channel,
&socket_fd, flag, callingUid);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Socket connection failed: %d", status);
@@ -1205,8 +1204,7 @@
return;
}
- sBluetoothInterface->interop_database_add(feature, (bt_bdaddr_t*)addr,
- length);
+ sBluetoothInterface->interop_database_add(feature, (RawAddress*)addr, length);
env->ReleaseByteArrayElements(address, addr, 0);
}
diff --git a/jni/com_android_bluetooth_gatt.cpp b/jni/com_android_bluetooth_gatt.cpp
index 9e721aa..e57a1d0 100644
--- a/jni/com_android_bluetooth_gatt.cpp
+++ b/jni/com_android_bluetooth_gatt.cpp
@@ -40,7 +40,7 @@
#define BD_ADDR_LEN 6
-#define UUID_PARAMS(uuid_ptr) uuid_lsb(uuid_ptr), uuid_msb(uuid_ptr)
+#define UUID_PARAMS(uuid) uuid_lsb(uuid), uuid_msb(uuid)
static void set_uuid(uint8_t* uuid, jlong uuid_msb, jlong uuid_lsb) {
for (int i = 0; i != 8; ++i) {
@@ -49,67 +49,40 @@
}
}
-static uint64_t uuid_lsb(const bt_uuid_t* uuid) {
+static uint64_t uuid_lsb(const bt_uuid_t& uuid) {
uint64_t lsb = 0;
for (int i = 7; i >= 0; i--) {
lsb <<= 8;
- lsb |= uuid->uu[i];
+ lsb |= uuid.uu[i];
}
return lsb;
}
-static uint64_t uuid_msb(const bt_uuid_t* uuid) {
+static uint64_t uuid_msb(const bt_uuid_t& uuid) {
uint64_t msb = 0;
for (int i = 15; i >= 8; i--) {
msb <<= 8;
- msb |= uuid->uu[i];
+ msb |= uuid.uu[i];
}
return msb;
}
-static void bd_addr_str_to_addr(const char* str, uint8_t* bd_addr) {
- int i;
- char c;
+static RawAddress str2addr(JNIEnv* env, jstring address) {
+ RawAddress bd_addr;
+ const char* c_address = env->GetStringUTFChars(address, NULL);
+ if (!c_address) return bd_addr;
- c = *str++;
- for (i = 0; i < BD_ADDR_LEN; i++) {
- if (c >= '0' && c <= '9')
- bd_addr[i] = c - '0';
- else if (c >= 'a' && c <= 'z')
- bd_addr[i] = c - 'a' + 10;
- else // (c >= 'A' && c <= 'Z')
- bd_addr[i] = c - 'A' + 10;
+ RawAddress::FromString(std::string(c_address), bd_addr);
+ env->ReleaseStringUTFChars(address, c_address);
- c = *str++;
- if (c != ':') {
- bd_addr[i] <<= 4;
- if (c >= '0' && c <= '9')
- bd_addr[i] |= c - '0';
- else if (c >= 'a' && c <= 'z')
- bd_addr[i] |= c - 'a' + 10;
- else // (c >= 'A' && c <= 'Z')
- bd_addr[i] |= c - 'A' + 10;
-
- c = *str++;
- }
-
- c = *str++;
- }
+ return bd_addr;
}
-static void jstr2bdaddr(JNIEnv* env, bt_bdaddr_t* bda, jstring address) {
- const char* c_bda = env->GetStringUTFChars(address, NULL);
- if (c_bda != NULL && bda != NULL && strlen(c_bda) == 17) {
- bd_addr_str_to_addr(c_bda, bda->address);
- env->ReleaseStringUTFChars(address, c_bda);
- }
-}
-
-static jstring bdaddr2newjstr(JNIEnv* env, bt_bdaddr_t* bda) {
+static jstring bdaddr2newjstr(JNIEnv* env, const RawAddress* bda) {
char c_address[32];
snprintf(c_address, sizeof(c_address), "%02X:%02X:%02X:%02X:%02X:%02X",
bda->address[0], bda->address[1], bda->address[2], bda->address[3],
@@ -219,7 +192,8 @@
* BTA client callbacks
*/
-void btgattc_register_app_cb(int status, int clientIf, bt_uuid_t* app_uuid) {
+void btgattc_register_app_cb(int status, int clientIf,
+ const bt_uuid_t& app_uuid) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientRegistered, status,
@@ -227,7 +201,7 @@
}
void btgattc_scan_result_cb(uint16_t event_type, uint8_t addr_type,
- bt_bdaddr_t* bda, uint8_t primary_phy,
+ RawAddress* bda, uint8_t primary_phy,
uint8_t secondary_phy, uint8_t advertising_sid,
int8_t tx_power, int8_t rssi,
uint16_t periodic_adv_int,
@@ -248,22 +222,24 @@
periodic_adv_int, jb.get());
}
-void btgattc_open_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda) {
+void btgattc_open_cb(int conn_id, int status, int clientIf,
+ const RawAddress& bda) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jstring> address(sCallbackEnv.get(),
- bdaddr2newjstr(sCallbackEnv.get(), bda));
+ bdaddr2newjstr(sCallbackEnv.get(), &bda));
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnected, clientIf,
conn_id, status, address.get());
}
-void btgattc_close_cb(int conn_id, int status, int clientIf, bt_bdaddr_t* bda) {
+void btgattc_close_cb(int conn_id, int status, int clientIf,
+ const RawAddress& bda) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jstring> address(sCallbackEnv.get(),
- bdaddr2newjstr(sCallbackEnv.get(), bda));
+ bdaddr2newjstr(sCallbackEnv.get(), &bda));
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDisconnected, clientIf,
conn_id, status, address.get());
}
@@ -285,19 +261,19 @@
conn_id, status, registered, handle);
}
-void btgattc_notify_cb(int conn_id, btgatt_notify_params_t* p_data) {
+void btgattc_notify_cb(int conn_id, const btgatt_notify_params_t& p_data) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jstring> address(
- sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &p_data->bda));
+ sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &p_data.bda));
ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(),
- sCallbackEnv->NewByteArray(p_data->len));
- sCallbackEnv->SetByteArrayRegion(jb.get(), 0, p_data->len,
- (jbyte*)p_data->value);
+ sCallbackEnv->NewByteArray(p_data.len));
+ sCallbackEnv->SetByteArrayRegion(jb.get(), 0, p_data.len,
+ (jbyte*)p_data.value);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotify, conn_id,
- address.get(), p_data->handle, p_data->is_notify,
+ address.get(), p_data.handle, p_data.is_notify,
jb.get());
}
@@ -338,21 +314,21 @@
}
void btgattc_read_descriptor_cb(int conn_id, int status,
- btgatt_read_params_t* p_data) {
+ const btgatt_read_params_t& p_data) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), NULL);
- if (p_data->value.len != 0) {
- jb.reset(sCallbackEnv->NewByteArray(p_data->value.len));
- sCallbackEnv->SetByteArrayRegion(jb.get(), 0, p_data->value.len,
- (jbyte*)p_data->value.value);
+ if (p_data.value.len != 0) {
+ jb.reset(sCallbackEnv->NewByteArray(p_data.value.len));
+ sCallbackEnv->SetByteArrayRegion(jb.get(), 0, p_data.value.len,
+ (jbyte*)p_data.value.value);
} else {
jb.reset(sCallbackEnv->NewByteArray(1));
}
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadDescriptor, conn_id,
- status, p_data->handle, jb.get());
+ status, p_data.handle, jb.get());
}
void btgattc_write_descriptor_cb(int conn_id, int status, uint16_t handle) {
@@ -363,13 +339,13 @@
status, handle);
}
-void btgattc_remote_rssi_cb(int client_if, bt_bdaddr_t* bda, int rssi,
+void btgattc_remote_rssi_cb(int client_if, const RawAddress& bda, int rssi,
int status) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jstring> address(sCallbackEnv.get(),
- bdaddr2newjstr(sCallbackEnv.get(), bda));
+ bdaddr2newjstr(sCallbackEnv.get(), &bda));
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadRemoteRssi,
client_if, address.get(), rssi, status);
@@ -488,7 +464,7 @@
ScopedLocalRef<jobject> uuid(
env, env->NewObject(uuidClazz.get(), uuidConstructor,
- uuid_msb(&curr.uuid), uuid_lsb(&curr.uuid)));
+ uuid_msb(curr.uuid), uuid_lsb(curr.uuid)));
fid = env->GetFieldID(gattDbElementClazz.get(), "uuid", "Ljava/util/UUID;");
env->SetObjectField(element.get(), fid, uuid.get());
@@ -511,7 +487,8 @@
}
}
-void btgattc_get_gatt_db_cb(int conn_id, btgatt_db_element_t* db, int count) {
+void btgattc_get_gatt_db_cb(int conn_id, const btgatt_db_element_t* db,
+ int count) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -579,7 +556,7 @@
* BTA server callbacks
*/
-void btgatts_register_app_cb(int status, int server_if, bt_uuid_t* uuid) {
+void btgatts_register_app_cb(int status, int server_if, const bt_uuid_t& uuid) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerRegistered, status,
@@ -587,12 +564,12 @@
}
void btgatts_connection_cb(int conn_id, int server_if, int connected,
- bt_bdaddr_t* bda) {
+ const RawAddress& bda) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jstring> address(sCallbackEnv.get(),
- bdaddr2newjstr(sCallbackEnv.get(), bda));
+ bdaddr2newjstr(sCallbackEnv.get(), &bda));
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientConnected,
address.get(), connected, conn_id, server_if);
}
@@ -631,41 +608,42 @@
}
void btgatts_request_read_characteristic_cb(int conn_id, int trans_id,
- bt_bdaddr_t* bda, int attr_handle,
- int offset, bool is_long) {
+ const RawAddress& bda,
+ int attr_handle, int offset,
+ bool is_long) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jstring> address(sCallbackEnv.get(),
- bdaddr2newjstr(sCallbackEnv.get(), bda));
+ bdaddr2newjstr(sCallbackEnv.get(), &bda));
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerReadCharacteristic,
address.get(), conn_id, trans_id, attr_handle,
offset, is_long);
}
void btgatts_request_read_descriptor_cb(int conn_id, int trans_id,
- bt_bdaddr_t* bda, int attr_handle,
+ const RawAddress& bda, int attr_handle,
int offset, bool is_long) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jstring> address(sCallbackEnv.get(),
- bdaddr2newjstr(sCallbackEnv.get(), bda));
+ bdaddr2newjstr(sCallbackEnv.get(), &bda));
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerReadDescriptor,
address.get(), conn_id, trans_id, attr_handle,
offset, is_long);
}
void btgatts_request_write_characteristic_cb(int conn_id, int trans_id,
- bt_bdaddr_t* bda, int attr_handle,
- int offset, bool need_rsp,
- bool is_prep,
+ const RawAddress& bda,
+ int attr_handle, int offset,
+ bool need_rsp, bool is_prep,
std::vector<uint8_t> value) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jstring> address(sCallbackEnv.get(),
- bdaddr2newjstr(sCallbackEnv.get(), bda));
+ bdaddr2newjstr(sCallbackEnv.get(), &bda));
ScopedLocalRef<jbyteArray> val(sCallbackEnv.get(),
sCallbackEnv->NewByteArray(value.size()));
if (val.get())
@@ -678,7 +656,7 @@
}
void btgatts_request_write_descriptor_cb(int conn_id, int trans_id,
- bt_bdaddr_t* bda, int attr_handle,
+ const RawAddress& bda, int attr_handle,
int offset, bool need_rsp,
bool is_prep,
std::vector<uint8_t> value) {
@@ -686,7 +664,7 @@
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jstring> address(sCallbackEnv.get(),
- bdaddr2newjstr(sCallbackEnv.get(), bda));
+ bdaddr2newjstr(sCallbackEnv.get(), &bda));
ScopedLocalRef<jbyteArray> val(sCallbackEnv.get(),
sCallbackEnv->NewByteArray(value.size()));
if (val.get())
@@ -698,13 +676,13 @@
val.get());
}
-void btgatts_request_exec_write_cb(int conn_id, int trans_id, bt_bdaddr_t* bda,
- int exec_write) {
+void btgatts_request_exec_write_cb(int conn_id, int trans_id,
+ const RawAddress& bda, int exec_write) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jstring> address(sCallbackEnv.get(),
- bdaddr2newjstr(sCallbackEnv.get(), bda));
+ bdaddr2newjstr(sCallbackEnv.get(), &bda));
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteWrite,
address.get(), conn_id, trans_id, exec_write);
}
@@ -848,7 +826,7 @@
method_onGetGattDb =
env->GetMethodID(clazz, "onGetGattDb", "(ILjava/util/ArrayList;)V");
method_onClientPhyRead =
- env->GetMethodID(clazz, "onClientPhyRead", "(IIII)V");
+ env->GetMethodID(clazz, "onClientPhyRead", "(ILjava/lang/String;III)V");
method_onClientPhyUpdate =
env->GetMethodID(clazz, "onClientPhyUpdate", "(IIII)V");
method_onClientConnUpdate =
@@ -884,7 +862,7 @@
env->GetMethodID(clazz, "onServerCongestion", "(IZ)V");
method_onServerMtuChanged = env->GetMethodID(clazz, "onMtuChanged", "(II)V");
method_onServerPhyRead =
- env->GetMethodID(clazz, "onServerPhyRead", "(IIII)V");
+ env->GetMethodID(clazz, "onServerPhyRead", "(ILjava/lang/String;III)V");
method_onServerPhyUpdate =
env->GetMethodID(clazz, "onServerPhyUpdate", "(IIII)V");
method_onServerConnUpdate =
@@ -955,9 +933,7 @@
static int gattClientGetDeviceTypeNative(JNIEnv* env, jobject object,
jstring address) {
if (!sGattIf) return 0;
- bt_bdaddr_t bda;
- jstr2bdaddr(env, &bda, address);
- return sGattIf->client->get_device_type(&bda);
+ return sGattIf->client->get_device_type(str2addr(env, address));
}
static void gattClientRegisterAppNative(JNIEnv* env, jobject object,
@@ -967,7 +943,7 @@
if (!sGattIf) return;
set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb);
- sGattIf->client->register_client(&uuid);
+ sGattIf->client->register_client(uuid);
}
static void gattClientUnregisterAppNative(JNIEnv* env, jobject object,
@@ -981,7 +957,7 @@
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScannerRegistered,
- status, scannerId, UUID_PARAMS(&app_uuid));
+ status, scannerId, UUID_PARAMS(app_uuid));
}
static void registerScannerNative(JNIEnv* env, jobject object,
@@ -1012,51 +988,51 @@
jint initiating_phys) {
if (!sGattIf) return;
- bt_bdaddr_t bda;
- jstr2bdaddr(env, &bda, address);
- sGattIf->client->connect(clientif, &bda, isDirect, transport, opportunistic,
- initiating_phys);
+ sGattIf->client->connect(clientif, str2addr(env, address), isDirect,
+ transport, opportunistic, initiating_phys);
}
static void gattClientDisconnectNative(JNIEnv* env, jobject object,
jint clientIf, jstring address,
jint conn_id) {
if (!sGattIf) return;
- bt_bdaddr_t bda;
- jstr2bdaddr(env, &bda, address);
- sGattIf->client->disconnect(clientIf, &bda, conn_id);
+ sGattIf->client->disconnect(clientIf, str2addr(env, address), conn_id);
}
static void gattClientSetPreferredPhyNative(JNIEnv* env, jobject object,
- jint clientIf, jint conn_id,
+ jint clientIf, jstring address,
jint tx_phy, jint rx_phy,
jint phy_options) {
if (!sGattIf) return;
- sGattIf->client->set_preferred_phy(conn_id, tx_phy, rx_phy, phy_options);
+ sGattIf->client->set_preferred_phy(str2addr(env, address), tx_phy, rx_phy,
+ phy_options);
}
-static void readClientPhyCb(int conn_id, uint8_t tx_phy, uint8_t rx_phy,
- uint8_t status) {
+static void readClientPhyCb(uint8_t clientIf, RawAddress bda, uint8_t tx_phy,
+ uint8_t rx_phy, uint8_t status) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
- sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientPhyRead, conn_id,
- tx_phy, rx_phy, status);
+ ScopedLocalRef<jstring> address(sCallbackEnv.get(),
+ bdaddr2newjstr(sCallbackEnv.get(), &bda));
+
+ sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientPhyRead, clientIf,
+ address.get(), tx_phy, rx_phy, status);
}
static void gattClientReadPhyNative(JNIEnv* env, jobject object, jint clientIf,
- jint conn_id) {
+ jstring address) {
if (!sGattIf) return;
- sGattIf->client->read_phy(conn_id, base::Bind(readClientPhyCb, conn_id));
+
+ RawAddress bda = str2addr(env, address);
+ sGattIf->client->read_phy(bda, base::Bind(&readClientPhyCb, clientIf, bda));
}
static void gattClientRefreshNative(JNIEnv* env, jobject object, jint clientIf,
jstring address) {
if (!sGattIf) return;
- bt_bdaddr_t bda;
- jstr2bdaddr(env, &bda, address);
- sGattIf->client->refresh(clientIf, &bda);
+ sGattIf->client->refresh(clientIf, str2addr(env, address));
}
static void gattClientSearchServiceNative(JNIEnv* env, jobject object,
@@ -1078,7 +1054,7 @@
bt_uuid_t uuid;
set_uuid(uuid.uu, service_uuid_msb, service_uuid_lsb);
- sGattIf->client->btif_gattc_discover_service_by_uuid(conn_id, &uuid);
+ sGattIf->client->btif_gattc_discover_service_by_uuid(conn_id, uuid);
}
static void gattClientGetGattDbNative(JNIEnv* env, jobject object,
@@ -1103,7 +1079,7 @@
bt_uuid_t uuid;
set_uuid(uuid.uu, uuid_msb, uuid_lsb);
- sGattIf->client->read_using_characteristic_uuid(conn_id, &uuid, s_handle,
+ sGattIf->client->read_using_characteristic_uuid(conn_id, uuid, s_handle,
e_handle, authReq);
}
@@ -1169,24 +1145,18 @@
jboolean enable) {
if (!sGattIf) return;
- bt_bdaddr_t bd_addr;
- const char* c_address = env->GetStringUTFChars(address, NULL);
- bd_addr_str_to_addr(c_address, bd_addr.address);
-
+ RawAddress bd_addr = str2addr(env, address);
if (enable)
- sGattIf->client->register_for_notification(clientIf, &bd_addr, handle);
+ sGattIf->client->register_for_notification(clientIf, bd_addr, handle);
else
- sGattIf->client->deregister_for_notification(clientIf, &bd_addr, handle);
+ sGattIf->client->deregister_for_notification(clientIf, bd_addr, handle);
}
static void gattClientReadRemoteRssiNative(JNIEnv* env, jobject object,
jint clientif, jstring address) {
if (!sGattIf) return;
- bt_bdaddr_t bda;
- jstr2bdaddr(env, &bda, address);
-
- sGattIf->client->read_remote_rssi(clientif, &bda);
+ sGattIf->client->read_remote_rssi(clientif, str2addr(env, address));
}
void set_scan_params_cmpl_cb(int client_if, uint8_t status) {
@@ -1300,8 +1270,7 @@
switch (filt_type) {
case 0: // BTM_BLE_PF_ADDR_FILTER
{
- bt_bdaddr_t bda;
- jstr2bdaddr(env, &bda, address);
+ RawAddress bda = str2addr(env, address);
sGattIf->scanner->ScanFilterAddRemove(
action, filt_type, filt_index, 0, 0, NULL, NULL, &bda, addr_type, {},
{}, base::Bind(&scan_filter_cfg_cb, client_if));
@@ -1442,10 +1411,8 @@
jint max_interval, jint latency,
jint timeout) {
if (!sGattIf) return;
- bt_bdaddr_t bda;
- jstr2bdaddr(env, &bda, address);
- sGattIf->client->conn_parameter_update(&bda, min_interval, max_interval,
- latency, timeout);
+ sGattIf->client->conn_parameter_update(str2addr(env, address), min_interval,
+ max_interval, latency, timeout);
}
void batchscan_cfg_storage_cb(uint8_t client_if, uint8_t status) {
@@ -1505,7 +1472,7 @@
bt_uuid_t uuid;
if (!sGattIf) return;
set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb);
- sGattIf->server->register_server(&uuid);
+ sGattIf->server->register_server(uuid);
}
static void gattServerUnregisterAppNative(JNIEnv* env, jobject object,
@@ -1519,43 +1486,44 @@
jint transport) {
if (!sGattIf) return;
- bt_bdaddr_t bd_addr;
- const char* c_address = env->GetStringUTFChars(address, NULL);
- bd_addr_str_to_addr(c_address, bd_addr.address);
-
- sGattIf->server->connect(server_if, &bd_addr, is_direct, transport);
+ RawAddress bd_addr = str2addr(env, address);
+ sGattIf->server->connect(server_if, bd_addr, is_direct, transport);
}
static void gattServerDisconnectNative(JNIEnv* env, jobject object,
jint serverIf, jstring address,
jint conn_id) {
if (!sGattIf) return;
- bt_bdaddr_t bda;
- jstr2bdaddr(env, &bda, address);
- sGattIf->server->disconnect(serverIf, &bda, conn_id);
+ sGattIf->server->disconnect(serverIf, str2addr(env, address), conn_id);
}
static void gattServerSetPreferredPhyNative(JNIEnv* env, jobject object,
- jint serverIf, jint conn_id,
+ jint serverIf, jstring address,
jint tx_phy, jint rx_phy,
jint phy_options) {
if (!sGattIf) return;
- sGattIf->server->set_preferred_phy(conn_id, tx_phy, rx_phy, phy_options);
+ RawAddress bda = str2addr(env, address);
+ sGattIf->server->set_preferred_phy(bda, tx_phy, rx_phy, phy_options);
}
-static void readServerPhyCb(int conn_id, uint8_t tx_phy, uint8_t rx_phy,
- uint8_t status) {
+static void readServerPhyCb(uint8_t serverIf, RawAddress bda, uint8_t tx_phy,
+ uint8_t rx_phy, uint8_t status) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
- sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerPhyRead, conn_id,
- tx_phy, rx_phy, status);
+ ScopedLocalRef<jstring> address(sCallbackEnv.get(),
+ bdaddr2newjstr(sCallbackEnv.get(), &bda));
+
+ sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerPhyRead, serverIf,
+ address.get(), tx_phy, rx_phy, status);
}
static void gattServerReadPhyNative(JNIEnv* env, jobject object, jint serverIf,
- jint conn_id) {
+ jstring address) {
if (!sGattIf) return;
- sGattIf->server->read_phy(conn_id, base::Bind(readServerPhyCb, conn_id));
+
+ RawAddress bda = str2addr(env, address);
+ sGattIf->server->read_phy(bda, base::Bind(&readServerPhyCb, serverIf, bda));
}
static void gattServerAddServiceNative(JNIEnv* env, jobject object,
@@ -1696,7 +1664,7 @@
env->ReleaseByteArrayElements(val, array, JNI_ABORT);
}
- sGattIf->server->send_response(conn_id, trans_id, status, &response);
+ sGattIf->server->send_response(conn_id, trans_id, status, response);
}
static void advertiseClassInitNative(JNIEnv* env, jclass clazz) {
@@ -1875,7 +1843,7 @@
}
static void getOwnAddressCb(uint8_t advertiser_id, uint8_t address_type,
- bt_bdaddr_t address) {
+ RawAddress address) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -2026,8 +1994,8 @@
}
static void onSyncStarted(int reg_id, uint8_t status, uint16_t sync_handle,
- uint8_t sid, uint8_t address_type,
- bt_bdaddr_t address, uint8_t phy, uint16_t interval) {
+ uint8_t sid, uint8_t address_type, RawAddress address,
+ uint8_t phy, uint16_t interval) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -2064,12 +2032,10 @@
jint reg_id) {
if (!sGattIf) return;
- bt_bdaddr_t tmp;
- jstr2bdaddr(env, &tmp, address);
-
- sGattIf->scanner->StartSync(
- sid, tmp, skip, timeout, base::Bind(&onSyncStarted, reg_id),
- base::Bind(&onSyncReport), base::Bind(&onSyncLost));
+ 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) {
@@ -2083,8 +2049,7 @@
jint p1, jint p2, jint p3, jint p4, jint p5) {
if (!sGattIf) return;
- bt_bdaddr_t bt_bda1;
- jstr2bdaddr(env, &bt_bda1, bda1);
+ RawAddress bt_bda1 = str2addr(env, bda1);
bt_uuid_t uuid1;
set_uuid(uuid1.uu, uuid1_msb, uuid1_lsb);
@@ -2097,7 +2062,7 @@
params.u3 = p3;
params.u4 = p4;
params.u5 = p5;
- sGattIf->client->test_command(command, ¶ms);
+ sGattIf->client->test_command(command, params);
}
/**
@@ -2191,9 +2156,10 @@
(void*)gattClientConnectNative},
{"gattClientDisconnectNative", "(ILjava/lang/String;I)V",
(void*)gattClientDisconnectNative},
- {"gattClientSetPreferredPhyNative", "(IIIII)V",
+ {"gattClientSetPreferredPhyNative", "(ILjava/lang/String;III)V",
(void*)gattClientSetPreferredPhyNative},
- {"gattClientReadPhyNative", "(II)V", (void*)gattClientReadPhyNative},
+ {"gattClientReadPhyNative", "(ILjava/lang/String;)V",
+ (void*)gattClientReadPhyNative},
{"gattClientRefreshNative", "(ILjava/lang/String;)V",
(void*)gattClientRefreshNative},
{"gattClientSearchServiceNative", "(IZJJ)V",
@@ -2229,9 +2195,10 @@
(void*)gattServerConnectNative},
{"gattServerDisconnectNative", "(ILjava/lang/String;I)V",
(void*)gattServerDisconnectNative},
- {"gattServerSetPreferredPhyNative", "(IIIII)V",
+ {"gattServerSetPreferredPhyNative", "(ILjava/lang/String;III)V",
(void*)gattServerSetPreferredPhyNative},
- {"gattServerReadPhyNative", "(II)V", (void*)gattServerReadPhyNative},
+ {"gattServerReadPhyNative", "(ILjava/lang/String;)V",
+ (void*)gattServerReadPhyNative},
{"gattServerAddServiceNative", "(ILjava/util/List;)V",
(void*)gattServerAddServiceNative},
{"gattServerStopServiceNative", "(II)V",
diff --git a/jni/com_android_bluetooth_hdp.cpp b/jni/com_android_bluetooth_hdp.cpp
index c49854e..3abc243 100644
--- a/jni/com_android_bluetooth_hdp.cpp
+++ b/jni/com_android_bluetooth_hdp.cpp
@@ -42,13 +42,13 @@
app_id, (jint)state);
}
-static void channel_state_callback(int app_id, bt_bdaddr_t* bd_addr,
+static void channel_state_callback(int app_id, RawAddress* bd_addr,
int mdep_cfg_index, int channel_id,
bthl_channel_state_t state, int fd) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for channel state");
return;
@@ -64,7 +64,7 @@
}
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onChannelStateChanged,
app_id, addr.get(), mdep_cfg_index, channel_id,
@@ -203,7 +203,7 @@
jint chan_id;
bt_status_t status = sBluetoothHdpInterface->connect_channel(
- app_id, (bt_bdaddr_t*)addr, 0, &chan_id);
+ app_id, (RawAddress*)addr, 0, &chan_id);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed HDP channel connection, status: %d", status);
chan_id = -1;
diff --git a/jni/com_android_bluetooth_hfp.cpp b/jni/com_android_bluetooth_hfp.cpp
index 863c7a3..5bb0d6e 100644
--- a/jni/com_android_bluetooth_hfp.cpp
+++ b/jni/com_android_bluetooth_hfp.cpp
@@ -55,22 +55,22 @@
static jobject mCallbacksObj = NULL;
static std::shared_timed_mutex callbacks_mutex;
-static jbyteArray marshall_bda(bt_bdaddr_t* bd_addr) {
+static jbyteArray marshall_bda(RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return NULL;
- jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+ jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(RawAddress));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr");
return NULL;
}
- sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(RawAddress),
(jbyte*)bd_addr);
return addr;
}
static void connection_state_callback(bthf_connection_state_t state,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
ALOGI("%s", __func__);
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
@@ -85,7 +85,7 @@
}
static void audio_state_callback(bthf_audio_state_t state,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
@@ -98,7 +98,7 @@
}
static void voice_recognition_callback(bthf_vr_state_t state,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
@@ -113,7 +113,7 @@
(jint)state, addr.get());
}
-static void answer_call_callback(bt_bdaddr_t* bd_addr) {
+static void answer_call_callback(RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
@@ -127,7 +127,7 @@
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAnswerCall, addr.get());
}
-static void hangup_call_callback(bt_bdaddr_t* bd_addr) {
+static void hangup_call_callback(RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
@@ -142,7 +142,7 @@
}
static void volume_control_callback(bthf_volume_type_t type, int volume,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
@@ -157,7 +157,7 @@
(jint)type, (jint)volume, addr.get());
}
-static void dial_call_callback(char* number, bt_bdaddr_t* bd_addr) {
+static void dial_call_callback(char* number, RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
@@ -174,7 +174,7 @@
js_number.get(), addr.get());
}
-static void dtmf_cmd_callback(char dtmf, bt_bdaddr_t* bd_addr) {
+static void dtmf_cmd_callback(char dtmf, RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
@@ -190,7 +190,7 @@
addr.get());
}
-static void noice_reduction_callback(bthf_nrec_t nrec, bt_bdaddr_t* bd_addr) {
+static void noice_reduction_callback(bthf_nrec_t nrec, RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
@@ -204,7 +204,7 @@
nrec == BTHF_NREC_START, addr.get());
}
-static void wbs_callback(bthf_wbs_config_t wbs_config, bt_bdaddr_t* bd_addr) {
+static void wbs_callback(bthf_wbs_config_t wbs_config, RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
@@ -216,25 +216,25 @@
addr.get());
}
-static void at_chld_callback(bthf_chld_type_t chld, bt_bdaddr_t* bd_addr) {
+static void at_chld_callback(bthf_chld_type_t chld, RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) {
ALOGE("Fail to new jbyteArray bd addr for audio state");
return;
}
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtChld, chld,
addr.get());
}
-static void at_cnum_callback(bt_bdaddr_t* bd_addr) {
+static void at_cnum_callback(RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
@@ -248,7 +248,7 @@
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCnum, addr.get());
}
-static void at_cind_callback(bt_bdaddr_t* bd_addr) {
+static void at_cind_callback(RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
@@ -262,7 +262,7 @@
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCind, addr.get());
}
-static void at_cops_callback(bt_bdaddr_t* bd_addr) {
+static void at_cops_callback(RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
@@ -276,7 +276,7 @@
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCops, addr.get());
}
-static void at_clcc_callback(bt_bdaddr_t* bd_addr) {
+static void at_clcc_callback(RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
@@ -290,7 +290,7 @@
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtClcc, addr.get());
}
-static void unknown_at_callback(char* at_string, bt_bdaddr_t* bd_addr) {
+static void unknown_at_callback(char* at_string, RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
@@ -307,7 +307,7 @@
js_at_string.get(), addr.get());
}
-static void key_pressed_callback(bt_bdaddr_t* bd_addr) {
+static void key_pressed_callback(RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
@@ -321,7 +321,7 @@
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onKeyPressed, addr.get());
}
-static void at_bind_callback(char* at_string, bt_bdaddr_t* bd_addr) {
+static void at_bind_callback(char* at_string, RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
@@ -337,7 +337,7 @@
}
static void at_biev_callback(bthf_hf_ind_type_t ind_id, int ind_value,
- bt_bdaddr_t* bd_addr) {
+ RawAddress* bd_addr) {
std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid() || mCallbacksObj == NULL) return;
@@ -479,7 +479,7 @@
return JNI_FALSE;
}
- bt_status_t status = sBluetoothHfpInterface->connect((bt_bdaddr_t*)addr);
+ bt_status_t status = sBluetoothHfpInterface->connect((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed HF connection, status: %d", status);
}
@@ -498,7 +498,7 @@
return JNI_FALSE;
}
- bt_status_t status = sBluetoothHfpInterface->disconnect((bt_bdaddr_t*)addr);
+ bt_status_t status = sBluetoothHfpInterface->disconnect((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed HF disconnection, status: %d", status);
}
@@ -517,8 +517,7 @@
return JNI_FALSE;
}
- bt_status_t status =
- sBluetoothHfpInterface->connect_audio((bt_bdaddr_t*)addr);
+ bt_status_t status = sBluetoothHfpInterface->connect_audio((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed HF audio connection, status: %d", status);
}
@@ -538,7 +537,7 @@
}
bt_status_t status =
- sBluetoothHfpInterface->disconnect_audio((bt_bdaddr_t*)addr);
+ sBluetoothHfpInterface->disconnect_audio((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed HF audio disconnection, status: %d", status);
}
@@ -558,7 +557,7 @@
}
bt_status_t status =
- sBluetoothHfpInterface->start_voice_recognition((bt_bdaddr_t*)addr);
+ sBluetoothHfpInterface->start_voice_recognition((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed to start voice recognition, status: %d", status);
}
@@ -578,7 +577,7 @@
}
bt_status_t status =
- sBluetoothHfpInterface->stop_voice_recognition((bt_bdaddr_t*)addr);
+ sBluetoothHfpInterface->stop_voice_recognition((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed to stop voice recognition, status: %d", status);
}
@@ -598,7 +597,7 @@
}
bt_status_t status = sBluetoothHfpInterface->volume_control(
- (bthf_volume_type_t)volume_type, volume, (bt_bdaddr_t*)addr);
+ (bthf_volume_type_t)volume_type, volume, (RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("FAILED to control volume, status: %d", status);
}
@@ -635,7 +634,7 @@
const char* operator_name = env->GetStringUTFChars(operator_str, NULL);
bt_status_t status =
- sBluetoothHfpInterface->cops_response(operator_name, (bt_bdaddr_t*)addr);
+ sBluetoothHfpInterface->cops_response(operator_name, (RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed sending cops response, status: %d", status);
}
@@ -661,7 +660,7 @@
bt_status_t status = sBluetoothHfpInterface->cind_response(
service, num_active, num_held, (bthf_call_state_t)call_state, signal,
- roam, battery_charge, (bt_bdaddr_t*)addr);
+ roam, battery_charge, (RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed cind_response, status: %d", status);
}
@@ -685,7 +684,7 @@
bt_status_t status = sBluetoothHfpInterface->bind_response(
(bthf_hf_ind_type_t)ind_id,
ind_status ? BTHF_HF_IND_ENABLED : BTHF_HF_IND_DISABLED,
- (bt_bdaddr_t*)addr);
+ (RawAddress*)addr);
if (status != BT_STATUS_SUCCESS)
ALOGE("%s: Failed bind_response, status: %d", __func__, status);
@@ -709,7 +708,7 @@
const char* response = env->GetStringUTFChars(response_str, NULL);
bt_status_t status = sBluetoothHfpInterface->formatted_at_response(
- response, (bt_bdaddr_t*)addr);
+ response, (RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed formatted AT response, status: %d", status);
}
@@ -731,7 +730,7 @@
}
bt_status_t status = sBluetoothHfpInterface->at_response(
- (bthf_at_response_t)response_code, cmee_code, (bt_bdaddr_t*)addr);
+ (bthf_at_response_t)response_code, cmee_code, (RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed AT response, status: %d", status);
}
@@ -759,7 +758,7 @@
index, (bthf_call_direction_t)dir, (bthf_call_state_t)callStatus,
(bthf_call_mode_t)mode,
mpty ? BTHF_CALL_MPTY_TYPE_MULTI : BTHF_CALL_MPTY_TYPE_SINGLE, number,
- (bthf_call_addrtype_t)type, (bt_bdaddr_t*)addr);
+ (bthf_call_addrtype_t)type, (RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed sending CLCC response, status: %d", status);
}
@@ -799,7 +798,7 @@
}
bt_status_t status = sBluetoothHfpInterface->configure_wbs(
- (bt_bdaddr_t*)addr, (bthf_wbs_config_t)codec_config);
+ (RawAddress*)addr, (bthf_wbs_config_t)codec_config);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed HF WBS codec config, status: %d", status);
}
@@ -807,6 +806,18 @@
return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}
+static jboolean setScoAllowedNative(JNIEnv* env, jobject object,
+ jboolean value) {
+ if (!sBluetoothHfpInterface) return JNI_FALSE;
+
+ bt_status_t status =
+ sBluetoothHfpInterface->set_sco_allowed(value == JNI_TRUE);
+ if (status != BT_STATUS_SUCCESS) {
+ ALOGE("Failed HF set sco allowed, status: %d", status);
+ }
+ return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
+}
+
static JNINativeMethod sMethods[] = {
{"classInitNative", "()V", (void*)classInitNative},
{"initializeNative", "(IZ)V", (void*)initializeNative},
@@ -832,6 +843,7 @@
{"phoneStateChangeNative", "(IIILjava/lang/String;I)Z",
(void*)phoneStateChangeNative},
{"configureWBSNative", "([BI)Z", (void*)configureWBSNative},
+ {"setScoAllowedNative", "(Z)Z", (void*)setScoAllowedNative},
};
int register_com_android_bluetooth_hfp(JNIEnv* env) {
diff --git a/jni/com_android_bluetooth_hfpclient.cpp b/jni/com_android_bluetooth_hfpclient.cpp
index 4bb1380..04e963b 100644
--- a/jni/com_android_bluetooth_hfpclient.cpp
+++ b/jni/com_android_bluetooth_hfpclient.cpp
@@ -50,21 +50,21 @@
static jmethodID method_onLastVoiceTagNumber;
static jmethodID method_onRingIndication;
-static jbyteArray marshall_bda(const bt_bdaddr_t* bd_addr) {
+static jbyteArray marshall_bda(const RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return NULL;
- jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+ jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(RawAddress));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr");
return NULL;
}
- sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(RawAddress),
(jbyte*)bd_addr);
return addr;
}
-static void connection_state_cb(const bt_bdaddr_t* bd_addr,
+static void connection_state_cb(const RawAddress* bd_addr,
bthf_client_connection_state_t state,
unsigned int peer_feat,
unsigned int chld_feat) {
@@ -80,7 +80,7 @@
addr.get());
}
-static void audio_state_cb(const bt_bdaddr_t* bd_addr,
+static void audio_state_cb(const RawAddress* bd_addr,
bthf_client_audio_state_t state) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -92,15 +92,14 @@
(jint)state, addr.get());
}
-static void vr_cmd_cb(const bt_bdaddr_t* bd_addr,
- bthf_client_vr_state_t state) {
+static void vr_cmd_cb(const RawAddress* bd_addr, bthf_client_vr_state_t state) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVrStateChanged,
(jint)state);
}
-static void network_state_cb(const bt_bdaddr_t* bd_addr,
+static void network_state_cb(const RawAddress* bd_addr,
bthf_client_network_state_t state) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -112,7 +111,7 @@
(jint)state, addr.get());
}
-static void network_roaming_cb(const bt_bdaddr_t* bd_addr,
+static void network_roaming_cb(const RawAddress* bd_addr,
bthf_client_service_type_t type) {
CallbackEnv sCallbackEnv(__func__);
@@ -123,7 +122,7 @@
(jint)type, addr.get());
}
-static void network_signal_cb(const bt_bdaddr_t* bd_addr, int signal) {
+static void network_signal_cb(const RawAddress* bd_addr, int signal) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -134,7 +133,7 @@
(jint)signal, addr.get());
}
-static void battery_level_cb(const bt_bdaddr_t* bd_addr, int level) {
+static void battery_level_cb(const RawAddress* bd_addr, int level) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -145,7 +144,7 @@
(jint)level, addr.get());
}
-static void current_operator_cb(const bt_bdaddr_t* bd_addr, const char* name) {
+static void current_operator_cb(const RawAddress* bd_addr, const char* name) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -158,7 +157,7 @@
js_name.get(), addr.get());
}
-static void call_cb(const bt_bdaddr_t* bd_addr, bthf_client_call_t call) {
+static void call_cb(const RawAddress* bd_addr, bthf_client_call_t call) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -169,7 +168,7 @@
addr.get());
}
-static void callsetup_cb(const bt_bdaddr_t* bd_addr,
+static void callsetup_cb(const RawAddress* bd_addr,
bthf_client_callsetup_t callsetup) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -185,7 +184,7 @@
(jint)callsetup, addr.get());
}
-static void callheld_cb(const bt_bdaddr_t* bd_addr,
+static void callheld_cb(const RawAddress* bd_addr,
bthf_client_callheld_t callheld) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -197,7 +196,7 @@
addr.get());
}
-static void resp_and_hold_cb(const bt_bdaddr_t* bd_addr,
+static void resp_and_hold_cb(const RawAddress* bd_addr,
bthf_client_resp_and_hold_t resp_and_hold) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -209,7 +208,7 @@
(jint)resp_and_hold, addr.get());
}
-static void clip_cb(const bt_bdaddr_t* bd_addr, const char* number) {
+static void clip_cb(const RawAddress* bd_addr, const char* number) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -222,7 +221,7 @@
addr.get());
}
-static void call_waiting_cb(const bt_bdaddr_t* bd_addr, const char* number) {
+static void call_waiting_cb(const RawAddress* bd_addr, const char* number) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -234,7 +233,7 @@
js_number.get(), addr.get());
}
-static void current_calls_cb(const bt_bdaddr_t* bd_addr, int index,
+static void current_calls_cb(const RawAddress* bd_addr, int index,
bthf_client_call_direction_t dir,
bthf_client_call_state_t state,
bthf_client_call_mpty_type_t mpty,
@@ -250,7 +249,7 @@
state, mpty, js_number.get(), addr.get());
}
-static void volume_change_cb(const bt_bdaddr_t* bd_addr,
+static void volume_change_cb(const RawAddress* bd_addr,
bthf_client_volume_type_t type, int volume) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -261,7 +260,7 @@
(jint)volume, addr.get());
}
-static void cmd_complete_cb(const bt_bdaddr_t* bd_addr,
+static void cmd_complete_cb(const RawAddress* bd_addr,
bthf_client_cmd_complete_t type, int cme) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -272,7 +271,7 @@
(jint)cme, addr.get());
}
-static void subscriber_info_cb(const bt_bdaddr_t* bd_addr, const char* name,
+static void subscriber_info_cb(const RawAddress* bd_addr, const char* name,
bthf_client_subscriber_service_type_t type) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -285,7 +284,7 @@
js_name.get(), (jint)type, addr.get());
}
-static void in_band_ring_cb(const bt_bdaddr_t* bd_addr,
+static void in_band_ring_cb(const RawAddress* bd_addr,
bthf_client_in_band_ring_state_t in_band) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -296,7 +295,7 @@
(jint)in_band, addr.get());
}
-static void last_voice_tag_number_cb(const bt_bdaddr_t* bd_addr,
+static void last_voice_tag_number_cb(const RawAddress* bd_addr,
const char* number) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -309,7 +308,7 @@
js_number.get(), addr.get());
}
-static void ring_indication_cb(const bt_bdaddr_t* bd_addr) {
+static void ring_indication_cb(const RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -445,8 +444,7 @@
return JNI_FALSE;
}
- bt_status_t status =
- sBluetoothHfpClientInterface->connect((bt_bdaddr_t*)addr);
+ bt_status_t status = sBluetoothHfpClientInterface->connect((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed AG connection, status: %d", status);
}
@@ -465,7 +463,7 @@
}
bt_status_t status =
- sBluetoothHfpClientInterface->disconnect((const bt_bdaddr_t*)addr);
+ sBluetoothHfpClientInterface->disconnect((const RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed AG disconnection, status: %d", status);
}
@@ -484,7 +482,7 @@
}
bt_status_t status =
- sBluetoothHfpClientInterface->connect_audio((const bt_bdaddr_t*)addr);
+ sBluetoothHfpClientInterface->connect_audio((const RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed AG audio connection, status: %d", status);
}
@@ -503,7 +501,7 @@
}
bt_status_t status =
- sBluetoothHfpClientInterface->disconnect_audio((const bt_bdaddr_t*)addr);
+ sBluetoothHfpClientInterface->disconnect_audio((const RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed AG audio disconnection, status: %d", status);
}
@@ -522,7 +520,7 @@
}
bt_status_t status = sBluetoothHfpClientInterface->start_voice_recognition(
- (const bt_bdaddr_t*)addr);
+ (const RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed to start voice recognition, status: %d", status);
}
@@ -541,7 +539,7 @@
}
bt_status_t status = sBluetoothHfpClientInterface->stop_voice_recognition(
- (const bt_bdaddr_t*)addr);
+ (const RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed to stop voice recognition, status: %d", status);
}
@@ -560,7 +558,7 @@
}
bt_status_t status = sBluetoothHfpClientInterface->volume_control(
- (const bt_bdaddr_t*)addr, (bthf_client_volume_type_t)volume_type, volume);
+ (const RawAddress*)addr, (bthf_client_volume_type_t)volume_type, volume);
if (status != BT_STATUS_SUCCESS) {
ALOGE("FAILED to control volume, status: %d", status);
}
@@ -584,7 +582,7 @@
}
bt_status_t status =
- sBluetoothHfpClientInterface->dial((const bt_bdaddr_t*)addr, number);
+ sBluetoothHfpClientInterface->dial((const RawAddress*)addr, number);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed to dial, status: %d", status);
}
@@ -606,7 +604,7 @@
}
bt_status_t status = sBluetoothHfpClientInterface->dial_memory(
- (const bt_bdaddr_t*)addr, (int)location);
+ (const RawAddress*)addr, (int)location);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed to dial from memory, status: %d", status);
}
@@ -627,7 +625,7 @@
}
bt_status_t status = sBluetoothHfpClientInterface->handle_call_action(
- (const bt_bdaddr_t*)addr, (bthf_client_call_action_t)action, (int)index);
+ (const RawAddress*)addr, (bthf_client_call_action_t)action, (int)index);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed to enter private mode, status: %d", status);
@@ -647,7 +645,7 @@
}
bt_status_t status = sBluetoothHfpClientInterface->query_current_calls(
- (const bt_bdaddr_t*)addr);
+ (const RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed to query current calls, status: %d", status);
@@ -668,7 +666,7 @@
bt_status_t status =
sBluetoothHfpClientInterface->query_current_operator_name(
- (const bt_bdaddr_t*)addr);
+ (const RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed to query current operator name, status: %d", status);
}
@@ -688,7 +686,7 @@
}
bt_status_t status = sBluetoothHfpClientInterface->retrieve_subscriber_info(
- (const bt_bdaddr_t*)addr);
+ (const RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed to retrieve subscriber info, status: %d", status);
}
@@ -708,7 +706,7 @@
}
bt_status_t status = sBluetoothHfpClientInterface->send_dtmf(
- (const bt_bdaddr_t*)addr, (char)code);
+ (const RawAddress*)addr, (char)code);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed to send DTMF, status: %d", status);
}
@@ -729,7 +727,7 @@
bt_status_t status =
sBluetoothHfpClientInterface->request_last_voice_tag_number(
- (const bt_bdaddr_t*)addr);
+ (const RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed to request last Voice Tag number, status: %d", status);
@@ -756,7 +754,7 @@
}
bt_status_t status = sBluetoothHfpClientInterface->send_at_cmd(
- (const bt_bdaddr_t*)addr, cmd, val1, val2, arg);
+ (const RawAddress*)addr, cmd, val1, val2, arg);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed to send cmd, status: %d", status);
diff --git a/jni/com_android_bluetooth_hid.cpp b/jni/com_android_bluetooth_hid.cpp
index d649063..8a58c29 100644
--- a/jni/com_android_bluetooth_hid.cpp
+++ b/jni/com_android_bluetooth_hid.cpp
@@ -37,21 +37,21 @@
static const bthh_interface_t* sBluetoothHidInterface = NULL;
static jobject mCallbacksObj = NULL;
-static jbyteArray marshall_bda(bt_bdaddr_t* bd_addr) {
+static jbyteArray marshall_bda(RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return NULL;
- jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+ jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(RawAddress));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr");
return NULL;
}
- sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(RawAddress),
(jbyte*)bd_addr);
return addr;
}
-static void connection_state_callback(bt_bdaddr_t* bd_addr,
+static void connection_state_callback(RawAddress* bd_addr,
bthh_connection_state_t state) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -69,7 +69,7 @@
addr.get(), (jint)state);
}
-static void get_protocol_mode_callback(bt_bdaddr_t* bd_addr,
+static void get_protocol_mode_callback(RawAddress* bd_addr,
bthh_status_t hh_status,
bthh_protocol_mode_t mode) {
CallbackEnv sCallbackEnv(__func__);
@@ -93,7 +93,7 @@
addr.get(), (jint)mode);
}
-static void get_report_callback(bt_bdaddr_t* bd_addr, bthh_status_t hh_status,
+static void get_report_callback(RawAddress* bd_addr, bthh_status_t hh_status,
uint8_t* rpt_data, int rpt_size) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -123,7 +123,7 @@
data.get(), (jint)rpt_size);
}
-static void virtual_unplug_callback(bt_bdaddr_t* bd_addr,
+static void virtual_unplug_callback(RawAddress* bd_addr,
bthh_status_t hh_status) {
ALOGV("call to virtual_unplug_callback");
CallbackEnv sCallbackEnv(__func__);
@@ -141,7 +141,7 @@
addr.get(), (jint)hh_status);
}
-static void handshake_callback(bt_bdaddr_t* bd_addr, bthh_status_t hh_status) {
+static void handshake_callback(RawAddress* bd_addr, bthh_status_t hh_status) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
if (!mCallbacksObj) {
@@ -158,8 +158,8 @@
(jint)hh_status);
}
-static void get_idle_time_callback(bt_bdaddr_t* bd_addr,
- bthh_status_t hh_status, int idle_time) {
+static void get_idle_time_callback(RawAddress* bd_addr, bthh_status_t hh_status,
+ int idle_time) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
@@ -265,7 +265,7 @@
}
jboolean ret = JNI_TRUE;
- bt_status_t status = sBluetoothHidInterface->connect((bt_bdaddr_t*)addr);
+ bt_status_t status = sBluetoothHidInterface->connect((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed HID channel connection, status: %d", status);
ret = JNI_FALSE;
@@ -287,7 +287,7 @@
return JNI_FALSE;
}
- bt_status_t status = sBluetoothHidInterface->disconnect((bt_bdaddr_t*)addr);
+ bt_status_t status = sBluetoothHidInterface->disconnect((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed disconnect hid channel, status: %d", status);
ret = JNI_FALSE;
@@ -311,7 +311,7 @@
// TODO: protocolMode is unused by the backend: see b/28908173
bthh_protocol_mode_t protocolMode = BTHH_UNSUPPORTED_MODE;
bt_status_t status = sBluetoothHidInterface->get_protocol(
- (bt_bdaddr_t*)addr, (bthh_protocol_mode_t)protocolMode);
+ (RawAddress*)addr, (bthh_protocol_mode_t)protocolMode);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed get protocol mode, status: %d", status);
ret = JNI_FALSE;
@@ -333,7 +333,7 @@
jboolean ret = JNI_TRUE;
bt_status_t status =
- sBluetoothHidInterface->virtual_unplug((bt_bdaddr_t*)addr);
+ sBluetoothHidInterface->virtual_unplug((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed virual unplug, status: %d", status);
ret = JNI_FALSE;
@@ -369,7 +369,7 @@
jboolean ret = JNI_TRUE;
bt_status_t status =
- sBluetoothHidInterface->set_protocol((bt_bdaddr_t*)addr, mode);
+ sBluetoothHidInterface->set_protocol((RawAddress*)addr, mode);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed set protocol mode, status: %d", status);
ret = JNI_FALSE;
@@ -396,7 +396,7 @@
jint rId = reportId;
bt_status_t status = sBluetoothHidInterface->get_report(
- (bt_bdaddr_t*)addr, (bthh_report_type_t)rType, (uint8_t)rId, bufferSize);
+ (RawAddress*)addr, (bthh_report_type_t)rType, (uint8_t)rId, bufferSize);
jboolean ret = JNI_TRUE;
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed get report, status: %d", status);
@@ -422,7 +422,7 @@
jboolean ret = JNI_TRUE;
bt_status_t status = sBluetoothHidInterface->set_report(
- (bt_bdaddr_t*)addr, (bthh_report_type_t)rType, (char*)c_report);
+ (RawAddress*)addr, (bthh_report_type_t)rType, (char*)c_report);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed set report, status: %d", status);
ret = JNI_FALSE;
@@ -448,7 +448,7 @@
const char* c_report = env->GetStringUTFChars(report, NULL);
bt_status_t status =
- sBluetoothHidInterface->send_data((bt_bdaddr_t*)addr, (char*)c_report);
+ sBluetoothHidInterface->send_data((RawAddress*)addr, (char*)c_report);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed set data, status: %d", status);
ret = JNI_FALSE;
@@ -469,7 +469,7 @@
return JNI_FALSE;
}
- bt_status_t status = sBluetoothHidInterface->get_idle_time((bt_bdaddr_t*)addr);
+ bt_status_t status = sBluetoothHidInterface->get_idle_time((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
ALOGE("%s: Failed get idle time, status: %d", __func__, status);
}
@@ -488,8 +488,8 @@
return JNI_FALSE;
}
- bt_status_t status = sBluetoothHidInterface->set_idle_time(
- (bt_bdaddr_t*)addr, idle_time);
+ bt_status_t status =
+ sBluetoothHidInterface->set_idle_time((RawAddress*)addr, idle_time);
if (status != BT_STATUS_SUCCESS) {
ALOGE("%s: Failed set idle time, status: %d", __func__, status);
}
diff --git a/jni/com_android_bluetooth_hidd.cpp b/jni/com_android_bluetooth_hidd.cpp
index 5b0beec..b0e084a 100644
--- a/jni/com_android_bluetooth_hidd.cpp
+++ b/jni/com_android_bluetooth_hidd.cpp
@@ -38,21 +38,21 @@
static const bthd_interface_t* sHiddIf = NULL;
static jobject mCallbacksObj = NULL;
-static jbyteArray marshall_bda(bt_bdaddr_t* bd_addr) {
+static jbyteArray marshall_bda(RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return NULL;
- jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+ jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(RawAddress));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr");
return NULL;
}
- sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(RawAddress),
(jbyte*)bd_addr);
return addr;
}
-static void application_state_callback(bt_bdaddr_t* bd_addr,
+static void application_state_callback(RawAddress* bd_addr,
bthd_application_state_t state) {
jboolean registered = JNI_FALSE;
@@ -76,7 +76,7 @@
addr.get(), registered);
}
-static void connection_state_callback(bt_bdaddr_t* bd_addr,
+static void connection_state_callback(RawAddress* bd_addr,
bthd_connection_state_t state) {
CallbackEnv sCallbackEnv(__func__);
@@ -426,7 +426,7 @@
return JNI_FALSE;
}
- bt_status_t ret = sHiddIf->connect((bt_bdaddr_t*)addr);
+ bt_status_t ret = sHiddIf->connect((RawAddress*)addr);
ALOGV("%s: connect() returned %d", __FUNCTION__, ret);
diff --git a/jni/com_android_bluetooth_pan.cpp b/jni/com_android_bluetooth_pan.cpp
index 2786a80..85107a0 100644
--- a/jni/com_android_bluetooth_pan.cpp
+++ b/jni/com_android_bluetooth_pan.cpp
@@ -44,16 +44,16 @@
static const btpan_interface_t* sPanIf = NULL;
static jobject mCallbacksObj = NULL;
-static jbyteArray marshall_bda(const bt_bdaddr_t* bd_addr) {
+static jbyteArray marshall_bda(const RawAddress* bd_addr) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return NULL;
- jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+ jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(RawAddress));
if (!addr) {
ALOGE("Fail to new jbyteArray bd addr");
return NULL;
}
- sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(RawAddress),
(jbyte*)bd_addr);
return addr;
}
@@ -76,8 +76,8 @@
static void connection_state_callback(btpan_connection_state_t state,
bt_status_t error,
- const bt_bdaddr_t* bd_addr,
- int local_role, int remote_role) {
+ const RawAddress* bd_addr, int local_role,
+ int remote_role) {
debug("state:%d, local_role:%d, remote_role:%d", state, local_role,
remote_role);
if (mCallbacksObj == NULL) {
@@ -200,7 +200,7 @@
}
jboolean ret = JNI_TRUE;
- bt_status_t status = sPanIf->connect((bt_bdaddr_t*)addr, src_role, dest_role);
+ bt_status_t status = sPanIf->connect((RawAddress*)addr, src_role, dest_role);
if (status != BT_STATUS_SUCCESS) {
error("Failed PAN channel connection, status: %d", status);
ret = JNI_FALSE;
@@ -221,7 +221,7 @@
}
jboolean ret = JNI_TRUE;
- bt_status_t status = sPanIf->disconnect((bt_bdaddr_t*)addr);
+ bt_status_t status = sPanIf->disconnect((RawAddress*)addr);
if (status != BT_STATUS_SUCCESS) {
error("Failed disconnect pan channel, status: %d", status);
ret = JNI_FALSE;
diff --git a/jni/com_android_bluetooth_sdp.cpp b/jni/com_android_bluetooth_sdp.cpp
index fb68f47..f658413 100644
--- a/jni/com_android_bluetooth_sdp.cpp
+++ b/jni/com_android_bluetooth_sdp.cpp
@@ -59,7 +59,7 @@
static const btsdp_interface_t* sBluetoothSdpInterface = NULL;
-static void sdp_search_callback(bt_status_t status, bt_bdaddr_t* bd_addr,
+static void sdp_search_callback(bt_status_t status, RawAddress* bd_addr,
uint8_t* uuid_in, int record_size,
bluetooth_sdp_record* record);
@@ -135,7 +135,7 @@
}
ALOGD("%s UUID %.*s", __func__, 16, (uint8_t*)uuid);
- int ret = sBluetoothSdpInterface->sdp_search((bt_bdaddr_t*)addr,
+ int ret = sBluetoothSdpInterface->sdp_search((RawAddress*)addr,
(const uint8_t*)uuid);
if (ret != BT_STATUS_SUCCESS) {
ALOGE("SDP Search initialization failed: %d", ret);
@@ -146,21 +146,21 @@
return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}
-static void sdp_search_callback(bt_status_t status, bt_bdaddr_t* bd_addr,
+static void sdp_search_callback(bt_status_t status, RawAddress* bd_addr,
uint8_t* uuid_in, int count,
bluetooth_sdp_record* records) {
CallbackEnv sCallbackEnv(__func__);
if (!sCallbackEnv.valid()) return;
ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
if (!addr.get()) return;
ScopedLocalRef<jbyteArray> uuid(
sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_uuid_t)));
if (!uuid.get()) return;
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
(jbyte*)bd_addr);
sCallbackEnv->SetByteArrayRegion(uuid.get(), 0, sizeof(bt_uuid_t),
(jbyte*)uuid_in);
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index dc5135d..68d0e06 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -74,7 +74,7 @@
<string name="bt_error_btn_ok" msgid="5965151173011534240">"حسنًا"</string>
<string name="unknown_file" msgid="6092727753965095366">"ملف غير معروف"</string>
<string name="unknown_file_desc" msgid="480434281415453287">"ليس هناك تطبيق لمعالجة هذا النوع من الملفات. \n"</string>
- <string name="not_exist_file" msgid="3489434189599716133">"ليست هناك أية ملفات"</string>
+ <string name="not_exist_file" msgid="3489434189599716133">"ليست هناك أي ملفات"</string>
<string name="not_exist_file_desc" msgid="4059531573790529229">"الملف غير موجود. \n"</string>
<string name="enabling_progress_title" msgid="436157952334723406">"يرجى الانتظار…"</string>
<string name="enabling_progress_content" msgid="4601542238119927904">"جارٍ تشغيل البلوتوث..."</string>
diff --git a/res/values-en-rCA/config.xml b/res/values-en-rCA/config.xml
new file mode 100644
index 0000000..4f96544
--- /dev/null
+++ b/res/values-en-rCA/config.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009-2012 Broadcom Corporation
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="pairing_ui_package" msgid="6399948348712579121">"com.android.settings"</string>
+</resources>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..f43c385
--- /dev/null
+++ b/res/values-en-rCA/strings.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<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">"Access download manager."</string>
+ <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"Allows the application to access the Bluetooth Share manager and to use it to transfer files."</string>
+ <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Whitelist bluetooth device access."</string>
+ <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Allows the app to temporarily whitelist a Bluetooth device, allowing that device to send files to this device without user confirmation."</string>
+ <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
+ <string name="unknown_device" msgid="9221903979877041009">"Unknown device"</string>
+ <string name="unknownNumber" msgid="4994750948072751566">"Unknown"</string>
+ <string name="airplane_error_title" msgid="2683839635115739939">"Airplane mode"</string>
+ <string name="airplane_error_msg" msgid="8698965595254137230">"You can\'t use Bluetooth in Airplane mode."</string>
+ <string name="bt_enable_title" msgid="8657832550503456572"></string>
+ <string name="bt_enable_line1" msgid="7203551583048149">"To use Bluetooth services, you must first turn on Bluetooth."</string>
+ <string name="bt_enable_line2" msgid="4341936569415937994">"Turn on Bluetooth now?"</string>
+ <string name="bt_enable_cancel" msgid="1988832367505151727">"Cancel"</string>
+ <string name="bt_enable_ok" msgid="3432462749994538265">"Turn on"</string>
+ <string name="incoming_file_confirm_title" msgid="8139874248612182627">"File transfer"</string>
+ <string name="incoming_file_confirm_content" msgid="2752605552743148036">"Accept incoming file?"</string>
+ <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Decline"</string>
+ <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Accept"</string>
+ <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
+ <string name="incoming_file_confirm_timeout_content" msgid="172779756093975981">"There was a timeout while accepting an incoming file from \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+ <string name="incoming_file_confirm_Notification_title" msgid="5573329005298936903">"Incoming file"</string>
+ <string name="incoming_file_confirm_Notification_content" msgid="3359694069319644738">"<xliff:g id="SENDER">%1$s</xliff:g> is ready to send <xliff:g id="FILE">%2$s</xliff:g>"</string>
+ <string name="notification_receiving" msgid="4674648179652543984">"Bluetooth share: Receiving <xliff:g id="FILE">%1$s</xliff:g>"</string>
+ <string name="notification_received" msgid="3324588019186687985">"Bluetooth share: Received <xliff:g id="FILE">%1$s</xliff:g>"</string>
+ <string name="notification_received_fail" msgid="3619350997285714746">"Bluetooth share: File <xliff:g id="FILE">%1$s</xliff:g> not received"</string>
+ <string name="notification_sending" msgid="3035748958534983833">"Bluetooth share: Sending <xliff:g id="FILE">%1$s</xliff:g>"</string>
+ <string name="notification_sent" msgid="9218710861333027778">"Bluetooth share: Sent <xliff:g id="FILE">%1$s</xliff:g>"</string>
+ <string name="notification_sent_complete" msgid="302943281067557969">"100% complete"</string>
+ <string name="notification_sent_fail" msgid="6696082233774569445">"Bluetooth share: File <xliff:g id="FILE">%1$s</xliff:g> not sent"</string>
+ <string name="download_title" msgid="3353228219772092586">"File transfer"</string>
+ <string name="download_line1" msgid="4926604799202134144">"From: \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+ <string name="download_line2" msgid="5876973543019417712">"File: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+ <string name="download_line3" msgid="4384821622908676061">"File size: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+ <string name="download_line4" msgid="8535996869722666525"></string>
+ <string name="download_line5" msgid="3069560415845295386">"Receiving file…"</string>
+ <string name="download_cancel" msgid="9177305996747500768">"Stop"</string>
+ <string name="download_ok" msgid="5000360731674466039">"Hide"</string>
+ <string name="incoming_line1" msgid="2127419875681087545">"From"</string>
+ <string name="incoming_line2" msgid="3348994249285315873">"Filename"</string>
+ <string name="incoming_line3" msgid="7954237069667474024">"Size"</string>
+ <string name="download_fail_line1" msgid="3846450148862894552">"File not received"</string>
+ <string name="download_fail_line2" msgid="8950394574689971071">"File: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+ <string name="download_fail_line3" msgid="3451040656154861722">"Reason: <xliff:g id="REASON">%1$s</xliff:g>"</string>
+ <string name="download_fail_ok" msgid="1521733664438320300">"OK"</string>
+ <string name="download_succ_line5" msgid="4509944688281573595">"File received"</string>
+ <string name="download_succ_ok" msgid="7053688246357050216">"Open"</string>
+ <string name="upload_line1" msgid="2055952074059709052">"To: \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+ <string name="upload_line3" msgid="4920689672457037437">"File type: <xliff:g id="TYPE">%1$s</xliff:g> (<xliff:g id="SIZE">%2$s</xliff:g>)"</string>
+ <string name="upload_line5" msgid="7759322537674229752">"Sending file…"</string>
+ <string name="upload_succ_line5" msgid="5687317197463383601">"File sent"</string>
+ <string name="upload_succ_ok" msgid="7705428476405478828">"OK"</string>
+ <string name="upload_fail_line1" msgid="7899394672421491701">"The file wasn\'t sent to \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\"."</string>
+ <string name="upload_fail_line1_2" msgid="2108129204050841798">"File: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+ <string name="upload_fail_ok" msgid="5807702461606714296">"Try again"</string>
+ <string name="upload_fail_cancel" msgid="9118496285835687125">"Close"</string>
+ <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
+ <string name="unknown_file" msgid="6092727753965095366">"Unknown file"</string>
+ <string name="unknown_file_desc" msgid="480434281415453287">"There\'s no app to handle this type of file. \n"</string>
+ <string name="not_exist_file" msgid="3489434189599716133">"No file"</string>
+ <string name="not_exist_file_desc" msgid="4059531573790529229">"The file doesn\'t exist. \n"</string>
+ <string name="enabling_progress_title" msgid="436157952334723406">"Please wait…"</string>
+ <string name="enabling_progress_content" msgid="4601542238119927904">"Turning on Bluetooth…"</string>
+ <string name="bt_toast_1" msgid="972182708034353383">"The file will be received. Check progress in the Notifications panel."</string>
+ <string name="bt_toast_2" msgid="8602553334099066582">"The file can\'t be received."</string>
+ <string name="bt_toast_3" msgid="6707884165086862518">"Stopped receiving file from \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+ <string name="bt_toast_4" msgid="4678812947604395649">"Sending file to \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+ <string name="bt_toast_5" msgid="2846870992823019494">"Sending <xliff:g id="NUMBER">%1$s</xliff:g> files to \"<xliff:g id="RECIPIENT">%2$s</xliff:g>\""</string>
+ <string name="bt_toast_6" msgid="1855266596936622458">"Stopped sending file to \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+ <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"There isn\'t enough space in USB storage to save the file from \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+ <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"There isn\'t enough space on the SD card to save the file from \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+ <string name="bt_sm_2_2" msgid="2965243265852680543">"Space needed: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+ <string name="ErrorTooManyRequests" msgid="8578277541472944529">"Too many requests are being processed. Try again later."</string>
+ <string name="status_pending" msgid="2503691772030877944">"File transfer not started yet"</string>
+ <string name="status_running" msgid="6562808920311008696">"File transfer is ongoing."</string>
+ <string name="status_success" msgid="239573225847565868">"File transfer completed successfully."</string>
+ <string name="status_not_accept" msgid="1695082417193780738">"Content isn\'t supported."</string>
+ <string name="status_forbidden" msgid="613956401054050725">"Transfer forbidden by target device."</string>
+ <string name="status_canceled" msgid="6664490318773098285">"Transfer cancelled by user."</string>
+ <string name="status_file_error" msgid="3671917770630165299">"Storage issue"</string>
+ <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"No USB storage."</string>
+ <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"No SD card. Insert an SD card to save transferred files."</string>
+ <string name="status_connection_error" msgid="947681831523219891">"Connection unsuccessful."</string>
+ <string name="status_protocol_error" msgid="3245444473429269539">"Request can\'t be handled correctly."</string>
+ <string name="status_unknown_error" msgid="8156660554237824912">"Unknown error."</string>
+ <string name="btopp_live_folder" msgid="7967791481444474554">"Bluetooth received"</string>
+ <string name="opp_notification_group" msgid="3486303082135789982">"Bluetooth Share"</string>
+ <string name="download_success" msgid="7036160438766730871">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> Received complete."</string>
+ <string name="upload_success" msgid="4014469387779648949">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> Sent complete."</string>
+ <string name="inbound_history_title" msgid="6940914942271327563">"Inbound transfers"</string>
+ <string name="outbound_history_title" msgid="4279418703178140526">"Outbound transfers"</string>
+ <string name="no_transfers" msgid="3482965619151865672">"Transfer history is empty."</string>
+ <string name="transfer_clear_dlg_msg" msgid="1712376797268438075">"All items will be cleared from the list."</string>
+ <string name="outbound_noti_title" msgid="8051906709452260849">"Bluetooth share: Sent files"</string>
+ <string name="inbound_noti_title" msgid="4143352641953027595">"Bluetooth share: Received files"</string>
+ <plurals name="noti_caption_unsuccessful" formatted="false" msgid="2020750076679526122">
+ <item quantity="other"><xliff:g id="UNSUCCESSFUL_NUMBER_1">%1$d</xliff:g> unsuccessful.</item>
+ <item quantity="one"><xliff:g id="UNSUCCESSFUL_NUMBER_0">%1$d</xliff:g> unsuccessful.</item>
+ </plurals>
+ <plurals name="noti_caption_success" formatted="false" msgid="1572472450257645181">
+ <item quantity="other"><xliff:g id="SUCCESSFUL_NUMBER_1">%1$d</xliff:g> successful, %2$s</item>
+ <item quantity="one"><xliff:g id="SUCCESSFUL_NUMBER_0">%1$d</xliff:g> successful, %2$s</item>
+ </plurals>
+ <string name="transfer_menu_clear_all" msgid="790017462957873132">"Clear list"</string>
+ <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_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_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>
+</resources>
diff --git a/res/values-en-rCA/strings_pbap.xml b/res/values-en-rCA/strings_pbap.xml
new file mode 100644
index 0000000..c80ccb6
--- /dev/null
+++ b/res/values-en-rCA/strings_pbap.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="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="auth_notif_ticker" msgid="1575825798053163744">"Obex authentication request"</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>
+ <string name="localPhoneName" msgid="2349001318925409159">"My name"</string>
+ <string name="defaultnumber" msgid="8520116145890867338">"000000"</string>
+ <string name="pbap_notification_group" msgid="8487669554703627168">"Bluetooth Contact share"</string>
+</resources>
diff --git a/res/values-en-rCA/strings_pbap_client.xml b/res/values-en-rCA/strings_pbap_client.xml
new file mode 100644
index 0000000..186b23a
--- /dev/null
+++ b/res/values-en-rCA/strings_pbap_client.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="pbap_account_type" msgid="6257077123906049322">"com.android.bluetooth.pbapsink"</string>
+</resources>
diff --git a/res/values-en-rCA/strings_sap.xml b/res/values-en-rCA/strings_sap.xml
new file mode 100644
index 0000000..c79b034
--- /dev/null
+++ b/res/values-en-rCA/strings_sap.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bluetooth_sap_notif_title" msgid="6877860822993195074">"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>
+ <string name="bluetooth_sap_notif_force_disconnect_button" msgid="8144086340185532030">"Force disconnect"</string>
+</resources>
diff --git a/res/values-en-rCA/test_strings.xml b/res/values-en-rCA/test_strings.xml
new file mode 100644
index 0000000..63128ee
--- /dev/null
+++ b/res/values-en-rCA/test_strings.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="6006644116867509664">"Bluetooth"</string>
+ <string name="insert_record" msgid="1450997173838378132">"Insert record"</string>
+ <string name="update_record" msgid="2480425402384910635">"Confirm record"</string>
+ <string name="ack_record" msgid="6716152390978472184">"Ack record"</string>
+ <string name="deleteAll_record" msgid="4383349788485210582">"Delete all record"</string>
+ <string name="ok_button" msgid="6519033415223065454">"OK"</string>
+ <string name="delete_record" msgid="4645040331967533724">"Delete record"</string>
+ <string name="start_server" msgid="9034821924409165795">"Start TCP server"</string>
+ <string name="notify_server" msgid="4369106744022969655">"Notify TCP server"</string>
+</resources>
diff --git a/res/values-en-rXC/config.xml b/res/values-en-rXC/config.xml
new file mode 100644
index 0000000..c77a0a4
--- /dev/null
+++ b/res/values-en-rXC/config.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009-2012 Broadcom Corporation
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="pairing_ui_package" msgid="6399948348712579121">"com.android.settings"</string>
+</resources>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..443e0a0
--- /dev/null
+++ b/res/values-en-rXC/strings.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<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">"Access download manager."</string>
+ <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"Allows the app to access the BluetoothShare manager and use it to transfer files."</string>
+ <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Whitelist bluetooth device access."</string>
+ <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Allows the app to temporarily whitelist a Bluetooth device, allowing that device to send files to this device without user confirmation."</string>
+ <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
+ <string name="unknown_device" msgid="9221903979877041009">"Unknown device"</string>
+ <string name="unknownNumber" msgid="4994750948072751566">"Unknown"</string>
+ <string name="airplane_error_title" msgid="2683839635115739939">"Airplane mode"</string>
+ <string name="airplane_error_msg" msgid="8698965595254137230">"You can\'t use Bluetooth in Airplane mode."</string>
+ <string name="bt_enable_title" msgid="8657832550503456572"></string>
+ <string name="bt_enable_line1" msgid="7203551583048149">"To use Bluetooth services, you must first turn on Bluetooth."</string>
+ <string name="bt_enable_line2" msgid="4341936569415937994">"Turn on Bluetooth now?"</string>
+ <string name="bt_enable_cancel" msgid="1988832367505151727">"Cancel"</string>
+ <string name="bt_enable_ok" msgid="3432462749994538265">"Turn on"</string>
+ <string name="incoming_file_confirm_title" msgid="8139874248612182627">"File transfer"</string>
+ <string name="incoming_file_confirm_content" msgid="2752605552743148036">"Accept incoming file?"</string>
+ <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Decline"</string>
+ <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Accept"</string>
+ <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
+ <string name="incoming_file_confirm_timeout_content" msgid="172779756093975981">"There was a timeout while accepting an incoming file from \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+ <string name="incoming_file_confirm_Notification_title" msgid="5573329005298936903">"Incoming file"</string>
+ <string name="incoming_file_confirm_Notification_content" msgid="3359694069319644738">"<xliff:g id="SENDER">%1$s</xliff:g> is ready to send <xliff:g id="FILE">%2$s</xliff:g>"</string>
+ <string name="notification_receiving" msgid="4674648179652543984">"Bluetooth share: Receiving <xliff:g id="FILE">%1$s</xliff:g>"</string>
+ <string name="notification_received" msgid="3324588019186687985">"Bluetooth share: Received <xliff:g id="FILE">%1$s</xliff:g>"</string>
+ <string name="notification_received_fail" msgid="3619350997285714746">"Bluetooth share: File <xliff:g id="FILE">%1$s</xliff:g> not received"</string>
+ <string name="notification_sending" msgid="3035748958534983833">"Bluetooth share: Sending <xliff:g id="FILE">%1$s</xliff:g>"</string>
+ <string name="notification_sent" msgid="9218710861333027778">"Bluetooth share: Sent <xliff:g id="FILE">%1$s</xliff:g>"</string>
+ <string name="notification_sent_complete" msgid="302943281067557969">"100% complete"</string>
+ <string name="notification_sent_fail" msgid="6696082233774569445">"Bluetooth share: File <xliff:g id="FILE">%1$s</xliff:g> not sent"</string>
+ <string name="download_title" msgid="3353228219772092586">"File transfer"</string>
+ <string name="download_line1" msgid="4926604799202134144">"From: \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+ <string name="download_line2" msgid="5876973543019417712">"File: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+ <string name="download_line3" msgid="4384821622908676061">"File size: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+ <string name="download_line4" msgid="8535996869722666525"></string>
+ <string name="download_line5" msgid="3069560415845295386">"Receiving file…"</string>
+ <string name="download_cancel" msgid="9177305996747500768">"Stop"</string>
+ <string name="download_ok" msgid="5000360731674466039">"Hide"</string>
+ <string name="incoming_line1" msgid="2127419875681087545">"From"</string>
+ <string name="incoming_line2" msgid="3348994249285315873">"Filename"</string>
+ <string name="incoming_line3" msgid="7954237069667474024">"Size"</string>
+ <string name="download_fail_line1" msgid="3846450148862894552">"File not received"</string>
+ <string name="download_fail_line2" msgid="8950394574689971071">"File: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+ <string name="download_fail_line3" msgid="3451040656154861722">"Reason: <xliff:g id="REASON">%1$s</xliff:g>"</string>
+ <string name="download_fail_ok" msgid="1521733664438320300">"OK"</string>
+ <string name="download_succ_line5" msgid="4509944688281573595">"File received"</string>
+ <string name="download_succ_ok" msgid="7053688246357050216">"Open"</string>
+ <string name="upload_line1" msgid="2055952074059709052">"To: \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+ <string name="upload_line3" msgid="4920689672457037437">"File type: <xliff:g id="TYPE">%1$s</xliff:g> (<xliff:g id="SIZE">%2$s</xliff:g>)"</string>
+ <string name="upload_line5" msgid="7759322537674229752">"Sending file…"</string>
+ <string name="upload_succ_line5" msgid="5687317197463383601">"File sent"</string>
+ <string name="upload_succ_ok" msgid="7705428476405478828">"OK"</string>
+ <string name="upload_fail_line1" msgid="7899394672421491701">"The file wasn\'t sent to \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\"."</string>
+ <string name="upload_fail_line1_2" msgid="2108129204050841798">"File: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+ <string name="upload_fail_ok" msgid="5807702461606714296">"Try again"</string>
+ <string name="upload_fail_cancel" msgid="9118496285835687125">"Close"</string>
+ <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
+ <string name="unknown_file" msgid="6092727753965095366">"Unknown file"</string>
+ <string name="unknown_file_desc" msgid="480434281415453287">"There\'s no app to handle this type of file. \n"</string>
+ <string name="not_exist_file" msgid="3489434189599716133">"No file"</string>
+ <string name="not_exist_file_desc" msgid="4059531573790529229">"The file doesn\'t exist. \n"</string>
+ <string name="enabling_progress_title" msgid="436157952334723406">"Please wait…"</string>
+ <string name="enabling_progress_content" msgid="4601542238119927904">"Turning on Bluetooth…"</string>
+ <string name="bt_toast_1" msgid="972182708034353383">"The file will be received. Check progress in the Notifications panel."</string>
+ <string name="bt_toast_2" msgid="8602553334099066582">"The file can\'t be received."</string>
+ <string name="bt_toast_3" msgid="6707884165086862518">"Stopped receiving file from \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+ <string name="bt_toast_4" msgid="4678812947604395649">"Sending file to \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+ <string name="bt_toast_5" msgid="2846870992823019494">"Sending <xliff:g id="NUMBER">%1$s</xliff:g> files to \"<xliff:g id="RECIPIENT">%2$s</xliff:g>\""</string>
+ <string name="bt_toast_6" msgid="1855266596936622458">"Stopped sending file to \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+ <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"There isn\'t enough space in USB storage to save the file from \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+ <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"There isn\'t enough space on the SD card to save the file from \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+ <string name="bt_sm_2_2" msgid="2965243265852680543">"Space needed: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+ <string name="ErrorTooManyRequests" msgid="8578277541472944529">"Too many requests are being processed. Try again later."</string>
+ <string name="status_pending" msgid="2503691772030877944">"File transfer not started yet."</string>
+ <string name="status_running" msgid="6562808920311008696">"File transfer is ongoing."</string>
+ <string name="status_success" msgid="239573225847565868">"File transfer completed successfully."</string>
+ <string name="status_not_accept" msgid="1695082417193780738">"Content isn\'t supported."</string>
+ <string name="status_forbidden" msgid="613956401054050725">"Transfer forbidden by target device."</string>
+ <string name="status_canceled" msgid="6664490318773098285">"Transfer canceled by user."</string>
+ <string name="status_file_error" msgid="3671917770630165299">"Storage issue."</string>
+ <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"No USB storage."</string>
+ <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"No SD card. Insert an SD card to save transferred files."</string>
+ <string name="status_connection_error" msgid="947681831523219891">"Connection unsuccessful."</string>
+ <string name="status_protocol_error" msgid="3245444473429269539">"Request can\'t be handled correctly."</string>
+ <string name="status_unknown_error" msgid="8156660554237824912">"Unknown error."</string>
+ <string name="btopp_live_folder" msgid="7967791481444474554">"Bluetooth received"</string>
+ <string name="opp_notification_group" msgid="3486303082135789982">"Bluetooth Share"</string>
+ <string name="download_success" msgid="7036160438766730871">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> Received complete."</string>
+ <string name="upload_success" msgid="4014469387779648949">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> Sent complete."</string>
+ <string name="inbound_history_title" msgid="6940914942271327563">"Inbound transfers"</string>
+ <string name="outbound_history_title" msgid="4279418703178140526">"Outbound transfers"</string>
+ <string name="no_transfers" msgid="3482965619151865672">"Transfer history is empty."</string>
+ <string name="transfer_clear_dlg_msg" msgid="1712376797268438075">"All items will be cleared from the list."</string>
+ <string name="outbound_noti_title" msgid="8051906709452260849">"Bluetooth share: Sent files"</string>
+ <string name="inbound_noti_title" msgid="4143352641953027595">"Bluetooth share: Received files"</string>
+ <plurals name="noti_caption_unsuccessful" formatted="false" msgid="2020750076679526122">
+ <item quantity="other"><xliff:g id="UNSUCCESSFUL_NUMBER_1">%1$d</xliff:g> unsuccessful.</item>
+ <item quantity="one"><xliff:g id="UNSUCCESSFUL_NUMBER_0">%1$d</xliff:g> unsuccessful.</item>
+ </plurals>
+ <plurals name="noti_caption_success" formatted="false" msgid="1572472450257645181">
+ <item quantity="other"><xliff:g id="SUCCESSFUL_NUMBER_1">%1$d</xliff:g> successful, %2$s</item>
+ <item quantity="one"><xliff:g id="SUCCESSFUL_NUMBER_0">%1$d</xliff:g> successful, %2$s</item>
+ </plurals>
+ <string name="transfer_menu_clear_all" msgid="790017462957873132">"Clear list"</string>
+ <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_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 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_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>
+</resources>
diff --git a/res/values-en-rXC/strings_pbap.xml b/res/values-en-rXC/strings_pbap.xml
new file mode 100644
index 0000000..fee6dbd
--- /dev/null
+++ b/res/values-en-rXC/strings_pbap.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="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="auth_notif_ticker" msgid="1575825798053163744">"Obex authentication request"</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">"Carkit"</string>
+ <string name="unknownName" msgid="2841414754740600042">"Unknown name"</string>
+ <string name="localPhoneName" msgid="2349001318925409159">"My name"</string>
+ <string name="defaultnumber" msgid="8520116145890867338">"000000"</string>
+ <string name="pbap_notification_group" msgid="8487669554703627168">"Bluetooth Contact share"</string>
+</resources>
diff --git a/res/values-en-rXC/strings_pbap_client.xml b/res/values-en-rXC/strings_pbap_client.xml
new file mode 100644
index 0000000..5d7540f
--- /dev/null
+++ b/res/values-en-rXC/strings_pbap_client.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="pbap_account_type" msgid="6257077123906049322">"com.android.bluetooth.pbapsink"</string>
+</resources>
diff --git a/res/values-en-rXC/strings_sap.xml b/res/values-en-rXC/strings_sap.xml
new file mode 100644
index 0000000..0b0524f
--- /dev/null
+++ b/res/values-en-rXC/strings_sap.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bluetooth_sap_notif_title" msgid="6877860822993195074">"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>
+ <string name="bluetooth_sap_notif_force_disconnect_button" msgid="8144086340185532030">"Force disconnect"</string>
+</resources>
diff --git a/res/values-en-rXC/test_strings.xml b/res/values-en-rXC/test_strings.xml
new file mode 100644
index 0000000..c0638ff
--- /dev/null
+++ b/res/values-en-rXC/test_strings.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="6006644116867509664">"Bluetooth"</string>
+ <string name="insert_record" msgid="1450997173838378132">"Insert record"</string>
+ <string name="update_record" msgid="2480425402384910635">"Confirm record"</string>
+ <string name="ack_record" msgid="6716152390978472184">"Ack record"</string>
+ <string name="deleteAll_record" msgid="4383349788485210582">"Delete all record"</string>
+ <string name="ok_button" msgid="6519033415223065454">"OK"</string>
+ <string name="delete_record" msgid="4645040331967533724">"Delete record"</string>
+ <string name="start_server" msgid="9034821924409165795">"Start TCP server"</string>
+ <string name="notify_server" msgid="4369106744022969655">"Notify TCP server"</string>
+</resources>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 835d146..4089e71 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -125,10 +125,10 @@
<string name="bluetooth_map_settings_save" msgid="7635491847388074606">"Gorde"</string>
<string name="bluetooth_map_settings_cancel" msgid="9205350798049865699">"Utzi"</string>
<string name="bluetooth_map_settings_intro" msgid="6482369468223987562">"Hautatu Bluetooth bidez partekatu nahi dituzun kontuak. Konektatzean, berariaz eman beharko duzu kontuetarako sarbidea."</string>
- <string name="bluetooth_map_settings_count" msgid="4557473074937024833">"Geratzen diren erretenak:"</string>
+ <string name="bluetooth_map_settings_count" msgid="4557473074937024833">"Geratzen diren zirrikituak:"</string>
<string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"Aplikazioaren ikonoa"</string>
<string name="bluetooth_map_settings_title" msgid="7420332483392851321">"Bluetooth bidez mezuak partekatzeko ezarpenak"</string>
- <string name="bluetooth_map_settings_no_account_slots_left" msgid="1796029082612965251">"Ezin da hautatu kontua. Ez da erretenik geratzen."</string>
+ <string name="bluetooth_map_settings_no_account_slots_left" msgid="1796029082612965251">"Ezin da hautatu kontua. Ez da geratzen zirrikiturik."</string>
<string name="bluetooth_connected" msgid="6718623220072656906">"Konektatu da Bluetooth bidezko audioa"</string>
<string name="bluetooth_disconnected" msgid="3318303728981478873">"Deskonektatu da Bluetooth bidezko audioa"</string>
<string name="a2dp_sink_mbs_label" msgid="7566075853395412558">"Bluetooth bidezko audioa"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 53ab99b..ca48a38 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -78,7 +78,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">"מפעיל Bluetooth…"</string>
- <string name="bt_toast_1" msgid="972182708034353383">"הקובץ יתקבל. בדוק את ההתקדמות בחלונית \'התראות\'."</string>
+ <string name="bt_toast_1" msgid="972182708034353383">"הקובץ יתקבל. בדוק את ההתקדמות בחלונית \'הודעות\'."</string>
<string name="bt_toast_2" msgid="8602553334099066582">"לא ניתן לקבל את הקובץ."</string>
<string name="bt_toast_3" msgid="6707884165086862518">"הופסקה קבלת קובץ מאת \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
<string name="bt_toast_4" msgid="4678812947604395649">"שולח קובץ אל \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 9c38985..37279c0 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -34,7 +34,7 @@
<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_ok" msgid="1414676773249857278">"OK"</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_content" msgid="3359694069319644738">"<xliff:g id="SENDER">%1$s</xliff:g> က <xliff:g id="FILE">%2$s</xliff:g>ကို ပို့ရန် အသင့်ပါ"</string>
@@ -59,19 +59,19 @@
<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">"OK"</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>
<string name="upload_line3" msgid="4920689672457037437">"ဖိုင်အမျိုးအစား - <xliff:g id="TYPE">%1$s</xliff:g> (<xliff:g id="SIZE">%2$s</xliff:g>)"</string>
<string name="upload_line5" msgid="7759322537674229752">"ဖိုင်ပို့နေပါသည်"</string>
<string name="upload_succ_line5" msgid="5687317197463383601">"ဖိုင်ပို့ပြီး"</string>
- <string name="upload_succ_ok" msgid="7705428476405478828">"အိုကေ"</string>
+ <string name="upload_succ_ok" msgid="7705428476405478828">"OK"</string>
<string name="upload_fail_line1" msgid="7899394672421491701">"\"<xliff:g id="RECIPIENT">%1$s</xliff:g>\"ထံသို့ ဖိုင်ကို မပို့ပါ"</string>
<string name="upload_fail_line1_2" msgid="2108129204050841798">"ဖိုင် - <xliff:g id="FILE">%1$s</xliff:g>"</string>
<string name="upload_fail_ok" msgid="5807702461606714296">"ပြန်ကြိုးစားပါ"</string>
<string name="upload_fail_cancel" msgid="9118496285835687125">"ပိတ်ရန်"</string>
- <string name="bt_error_btn_ok" msgid="5965151173011534240">"အိုကေ"</string>
+ <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
<string name="unknown_file" msgid="6092727753965095366">"အမျိုးအမည် မသိသောဖိုင်"</string>
<string name="unknown_file_desc" msgid="480434281415453287">"ဤဖိုင်အမျိုးအစားကို ကိုင်တွယ်ရန် အပလီကေးရှင်းမရှိပါ\n"</string>
<string name="not_exist_file" msgid="3489434189599716133">"ဖိုင်မရှိပါ"</string>
diff --git a/res/values-my/test_strings.xml b/res/values-my/test_strings.xml
index 34b8f8a..e9cf314 100644
--- a/res/values-my/test_strings.xml
+++ b/res/values-my/test_strings.xml
@@ -6,7 +6,7 @@
<string name="update_record" msgid="2480425402384910635">"မှတ်တမ်းအတည်ပြုရန်"</string>
<string name="ack_record" msgid="6716152390978472184">"အသိအမှတ်ပြု မှတ်တမ်း"</string>
<string name="deleteAll_record" msgid="4383349788485210582">"မှတ်တမ်းအားလုံးကို ဖျက်ရန်"</string>
- <string name="ok_button" msgid="6519033415223065454">"အိုကေ"</string>
+ <string name="ok_button" msgid="6519033415223065454">"OK"</string>
<string name="delete_record" msgid="4645040331967533724">"မှတ်တမ်းကို ဖျက်ရန်"</string>
<string name="start_server" msgid="9034821924409165795">"TCP ဆာဗာ စတင်ရန်"</string>
<string name="notify_server" msgid="4369106744022969655">"TCP ဆာဗာကို အကြောင်းကြားရန်"</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index da66b45..84030ba 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -101,7 +101,7 @@
<string name="status_protocol_error" msgid="3245444473429269539">"अनुरोधलाई सही रूपमा सम्हाल्न सकिँदैन।"</string>
<string name="status_unknown_error" msgid="8156660554237824912">"अज्ञात त्रुटि।"</string>
<string name="btopp_live_folder" msgid="7967791481444474554">"ब्लुटुथ प्राप्त भयो"</string>
- <string name="opp_notification_group" msgid="3486303082135789982">"ब्लुटुथमार्फत गरिने आदान-प्रदान"</string>
+ <string name="opp_notification_group" msgid="3486303082135789982">"ब्लुटुथमार्फत गरिने आदान प्रदान"</string>
<string name="download_success" msgid="7036160438766730871">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> प्राप्त गर्ने कार्य सम्पन्न भयो।"</string>
<string name="upload_success" msgid="4014469387779648949">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> पठाउने कार्य पुरा भयो।"</string>
<string name="inbound_history_title" msgid="6940914942271327563">"इनबाउन्ड स्थानान्तरण"</string>
diff --git a/res/values-ne/strings_pbap.xml b/res/values-ne/strings_pbap.xml
index dcd1b20..8d3167e 100644
--- a/res/values-ne/strings_pbap.xml
+++ b/res/values-ne/strings_pbap.xml
@@ -12,5 +12,5 @@
<string name="unknownName" msgid="2841414754740600042">"अज्ञात नाम"</string>
<string name="localPhoneName" msgid="2349001318925409159">"मेरो नाम"</string>
<string name="defaultnumber" msgid="8520116145890867338">"००००००"</string>
- <string name="pbap_notification_group" msgid="8487669554703627168">"ब्लुटुथमार्फत सम्पर्कको आदान-प्रदान"</string>
+ <string name="pbap_notification_group" msgid="8487669554703627168">"ब्लुटुथमार्फत सम्पर्कको आदान प्रदान"</string>
</resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index b95417b..05448c5 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -58,11 +58,15 @@
<bool name="headset_client_initial_audio_route_allowed">true</bool>
- <!-- For AVRCP absolute volume feature. If the threshold is non-zero,
- restrict the initial volume to the threshold.
- Valid value is 1-14, and recommended value is 8 -->
+ <!-- @deprecated: use a2dp_absolute_volume_initial_threshold_percent
+ instead. -->
<integer name="a2dp_absolute_volume_initial_threshold">8</integer>
+ <!-- AVRCP absolute volume initial value as percent of the maximum value.
+ Valid values are in the interval [0, 100].
+ Recommended value is 50. -->
+ <integer name="a2dp_absolute_volume_initial_threshold_percent">50</integer>
+
<!-- For A2DP sink ducking volume feature. -->
<integer name="a2dp_sink_duck_percent">25</integer>
diff --git a/src/com/android/bluetooth/a2dp/A2dpStateMachine.java b/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
index cca1533..7a18989 100755
--- a/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
+++ b/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
@@ -625,6 +625,10 @@
broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
BluetoothProfile.STATE_CONNECTING);
break;
+ } else {
+ broadcastConnectionState(mCurrentDevice,
+ BluetoothProfile.STATE_DISCONNECTING,
+ BluetoothProfile.STATE_CONNECTED);
}
synchronized (A2dpStateMachine.this) {
@@ -643,7 +647,7 @@
BluetoothProfile.STATE_CONNECTED);
if (!disconnectA2dpNative(getByteAddress(device))) {
broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTED,
- BluetoothProfile.STATE_DISCONNECTED);
+ BluetoothProfile.STATE_DISCONNECTING);
break;
}
synchronized (A2dpStateMachine.this) {
diff --git a/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java b/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java
index 33fe1ec..dae6df5 100644
--- a/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java
+++ b/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java
@@ -16,8 +16,10 @@
package com.android.bluetooth.a2dpsink;
+import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.media.AudioAttributes;
+import android.media.AudioFocusRequest;
import android.media.AudioManager;
import android.media.AudioManager.OnAudioFocusChangeListener;
import android.os.Handler;
@@ -27,6 +29,8 @@
import com.android.bluetooth.avrcpcontroller.AvrcpControllerService;
import com.android.bluetooth.R;
+import java.util.List;
+
/**
* Bluetooth A2DP SINK Streaming Handler.
*
@@ -209,8 +213,22 @@
* Utility functions.
*/
private int requestAudioFocus() {
- int focusRequestStatus = mAudioManager.requestAudioFocus(
- mAudioFocusListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
+ // Bluetooth A2DP may carry Music, Audio Books, Navigation, or other sounds so mark content
+ // type unknown.
+ AudioAttributes streamAttributes =
+ new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_MEDIA)
+ .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
+ .build();
+ // Bluetooth ducking is handled at the native layer so tell the Audio Manger to notify the
+ // focus change listener via .setWillPauseWhenDucked().
+ AudioFocusRequest focusRequest =
+ new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
+ .setAudioAttributes(streamAttributes)
+ .setWillPauseWhenDucked(true)
+ .setOnAudioFocusChangeListener(mAudioFocusListener, this)
+ .build();
+ int focusRequestStatus = mAudioManager.requestAudioFocus(focusRequest);
// If the request is granted begin streaming immediately and schedule an upgrade.
if (focusRequestStatus == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
startAvrcpUpdates();
@@ -275,16 +293,20 @@
if (DBG) {
Log.d(TAG, "sendAvrcpPause");
}
- if (avrcpService != null && avrcpService.getConnectedDevices().size() == 1) {
- if (DBG) {
- Log.d(TAG, "Pausing AVRCP.");
+ if (avrcpService != null) {
+ List<BluetoothDevice> connectedDevices = avrcpService.getConnectedDevices();
+ if (!connectedDevices.isEmpty()) {
+ BluetoothDevice targetDevice = connectedDevices.get(0);
+ if (DBG) {
+ Log.d(TAG, "Pausing AVRCP.");
+ }
+ avrcpService.sendPassThroughCmd(targetDevice,
+ AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE,
+ AvrcpControllerService.KEY_STATE_PRESSED);
+ avrcpService.sendPassThroughCmd(targetDevice,
+ AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE,
+ AvrcpControllerService.KEY_STATE_RELEASED);
}
- avrcpService.sendPassThroughCmd(avrcpService.getConnectedDevices().get(0),
- AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE,
- AvrcpControllerService.KEY_STATE_PRESSED);
- avrcpService.sendPassThroughCmd(avrcpService.getConnectedDevices().get(0),
- AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE,
- AvrcpControllerService.KEY_STATE_RELEASED);
} else {
Log.e(TAG, "Passthrough not sent, connection un-available.");
}
@@ -297,16 +319,20 @@
if (DBG) {
Log.d(TAG, "sendAvrcpPlay");
}
- if (avrcpService != null && avrcpService.getConnectedDevices().size() == 1) {
- if (DBG) {
- Log.d(TAG, "Playing AVRCP.");
+ if (avrcpService != null) {
+ List<BluetoothDevice> connectedDevices = avrcpService.getConnectedDevices();
+ if (!connectedDevices.isEmpty()) {
+ BluetoothDevice targetDevice = connectedDevices.get(0);
+ if (DBG) {
+ Log.d(TAG, "Playing AVRCP.");
+ }
+ avrcpService.sendPassThroughCmd(targetDevice,
+ AvrcpControllerService.PASS_THRU_CMD_ID_PLAY,
+ AvrcpControllerService.KEY_STATE_PRESSED);
+ avrcpService.sendPassThroughCmd(targetDevice,
+ AvrcpControllerService.PASS_THRU_CMD_ID_PLAY,
+ AvrcpControllerService.KEY_STATE_RELEASED);
}
- avrcpService.sendPassThroughCmd(avrcpService.getConnectedDevices().get(0),
- AvrcpControllerService.PASS_THRU_CMD_ID_PLAY,
- AvrcpControllerService.KEY_STATE_PRESSED);
- avrcpService.sendPassThroughCmd(avrcpService.getConnectedDevices().get(0),
- AvrcpControllerService.PASS_THRU_CMD_ID_PLAY,
- AvrcpControllerService.KEY_STATE_RELEASED);
} else {
Log.e(TAG, "Passthrough not sent, connection un-available.");
}
diff --git a/src/com/android/bluetooth/a2dpsink/mbs/A2dpMediaBrowserService.java b/src/com/android/bluetooth/a2dpsink/mbs/A2dpMediaBrowserService.java
index a43bb58..84dec4f 100644
--- a/src/com/android/bluetooth/a2dpsink/mbs/A2dpMediaBrowserService.java
+++ b/src/com/android/bluetooth/a2dpsink/mbs/A2dpMediaBrowserService.java
@@ -356,11 +356,12 @@
}
} else if (AvrcpControllerService.ACTION_TRACK_EVENT.equals(action)) {
PlaybackState pbb =
- intent.getParcelableExtra(AvrcpControllerService.EXTRA_PLAYBACK);
+ intent.getParcelableExtra(AvrcpControllerService.EXTRA_PLAYBACK);
MediaMetadata mmd =
- intent.getParcelableExtra(AvrcpControllerService.EXTRA_METADATA);
- mAvrcpCommandQueue.obtainMessage(
- MSG_TRACK, new Pair<PlaybackState, MediaMetadata>(pbb, mmd)).sendToTarget();
+ intent.getParcelableExtra(AvrcpControllerService.EXTRA_METADATA);
+ mAvrcpCommandQueue
+ .obtainMessage(MSG_TRACK, new Pair<PlaybackState, MediaMetadata>(pbb, mmd))
+ .sendToTarget();
} else if (AvrcpControllerService.ACTION_FOLDER_LIST.equals(action)) {
mAvrcpCommandQueue.obtainMessage(MSG_FOLDER_LIST, intent).sendToTarget();
}
@@ -432,6 +433,8 @@
// Set device to null.
mA2dpDevice = null;
mBrowseConnected = false;
+ // update playerList.
+ notifyChildrenChanged("__ROOT__");
}
private void msgTrack(PlaybackState pb, MediaMetadata mmd) {
@@ -506,6 +509,8 @@
return;
}
mBrowseConnected = true;
+ // update playerList
+ notifyChildrenChanged("__ROOT__");
}
private void msgFolderList(Intent intent) {
diff --git a/src/com/android/bluetooth/avrcp/AddressedMediaPlayer.java b/src/com/android/bluetooth/avrcp/AddressedMediaPlayer.java
index d2c941e..da19b32 100644
--- a/src/com/android/bluetooth/avrcp/AddressedMediaPlayer.java
+++ b/src/com/android/bluetooth/avrcp/AddressedMediaPlayer.java
@@ -57,14 +57,12 @@
private final List<MediaSession.QueueItem> mEmptyNowPlayingList;
private long mLastTrackIdSent;
- private boolean mNowPlayingListUpdated;
public AddressedMediaPlayer(AvrcpMediaRspInterface mediaInterface) {
mEmptyNowPlayingList = new ArrayList<MediaSession.QueueItem>();
mNowPlayingList = mEmptyNowPlayingList;
mMediaInterface = mediaInterface;
mLastTrackIdSent = MediaSession.QueueItem.UNKNOWN_ID;
- mNowPlayingListUpdated = false;
}
void cleanup() {
@@ -72,7 +70,6 @@
mNowPlayingList = mEmptyNowPlayingList;
mMediaInterface = null;
mLastTrackIdSent = MediaSession.QueueItem.UNKNOWN_ID;
- mNowPlayingListUpdated = false;
}
/* get now playing list from addressed player */
@@ -84,7 +81,7 @@
mMediaInterface.folderItemsRsp(bdaddr, AvrcpConstants.RSP_NO_AVBL_PLAY, null);
return;
}
- List<MediaSession.QueueItem> items = getNowPlayingList(mediaController);
+ List<MediaSession.QueueItem> items = updateNowPlayingList(mediaController);
getFolderItemsFilterAttr(bdaddr, reqObj, items, AvrcpConstants.BTRC_SCOPE_NOW_PLAYING,
reqObj.mStartItem, reqObj.mEndItem, mediaController);
}
@@ -94,17 +91,17 @@
@Nullable MediaController mediaController) {
int status = AvrcpConstants.RSP_NO_ERROR;
long mediaId = ByteBuffer.wrap(itemAttr.mUid).getLong();
- List<MediaSession.QueueItem> items = getNowPlayingList(mediaController);
+ List<MediaSession.QueueItem> items = updateNowPlayingList(mediaController);
// NOTE: this is out-of-spec (AVRCP 1.6.1 sec 6.10.4.3, p90) but we answer it anyway
// because some CTs ask for it.
if (Arrays.equals(itemAttr.mUid, AvrcpConstants.TRACK_IS_SELECTED)) {
- if (DEBUG) Log.d(TAG, "getItemAttr: Remote requests for now playing contents:");
-
- // get the current playing metadata and send.
- getItemAttrFilterAttr(bdaddr, itemAttr, getCurrentQueueItem(mediaController, mediaId),
- mediaController);
- return;
+ mediaId = getActiveQueueItemId(mediaController);
+ if (DEBUG) {
+ Log.d(TAG,
+ "getItemAttr: Remote requests for now playing contents, sending UID: "
+ + mediaId);
+ }
}
if (DEBUG) Log.d(TAG, "getItemAttr-UID: 0x" + Utils.byteArrayToString(itemAttr.mUid));
@@ -121,29 +118,43 @@
/* Refresh and get the queue of now playing.
*/
- private @NonNull List<MediaSession.QueueItem> getNowPlayingList(
- @Nullable MediaController mediaController) {
+ @NonNull
+ List<MediaSession.QueueItem> updateNowPlayingList(@Nullable MediaController mediaController) {
if (mediaController == null) return mEmptyNowPlayingList;
List<MediaSession.QueueItem> items = mediaController.getQueue();
- if (items != null && !mNowPlayingListUpdated) {
- mNowPlayingList = items;
- return mNowPlayingList;
- }
if (items == null) {
Log.i(TAG, "null queue from " + mediaController.getPackageName()
+ ", constructing single-item list");
- MediaMetadata metadata = mediaController.getMetadata();
+
// Because we are database-unaware, we can just number the item here whatever we want
// because they have to re-poll it every time.
- MediaSession.QueueItem current = getCurrentQueueItem(mediaController, SINGLE_QID);
+ MediaMetadata metadata = mediaController.getMetadata();
+ if (metadata == null) {
+ Log.w(TAG, "Controller has no metadata!? Making an empty one");
+ metadata = (new MediaMetadata.Builder()).build();
+ }
+
+ MediaDescription.Builder bob = new MediaDescription.Builder();
+ MediaDescription desc = metadata.getDescription();
+
+ // set the simple ones that MediaMetadata builds for us
+ bob.setMediaId(desc.getMediaId());
+ bob.setTitle(desc.getTitle());
+ bob.setSubtitle(desc.getSubtitle());
+ bob.setDescription(desc.getDescription());
+ // fill the ones that we use later
+ bob.setExtras(fillBundle(metadata, desc.getExtras()));
+
+ // build queue item with the new metadata
+ MediaSession.QueueItem current = new QueueItem(bob.build(), SINGLE_QID);
+
items = new ArrayList<MediaSession.QueueItem>();
items.add(current);
}
+ if (!items.equals(mNowPlayingList)) sendNowPlayingListChanged();
mNowPlayingList = items;
- if (mNowPlayingListUpdated) sendNowPlayingListChanged();
-
return mNowPlayingList;
}
@@ -151,40 +162,6 @@
if (mMediaInterface == null) return;
if (DEBUG) Log.d(TAG, "sendNowPlayingListChanged()");
mMediaInterface.nowPlayingChangedRsp(AvrcpConstants.NOTIFICATION_TYPE_CHANGED);
- mNowPlayingListUpdated = false;
- }
-
- /* Constructs a queue item representing the current playing metadata from an
- * active controller with queue id |qid|.
- */
- private MediaSession.QueueItem getCurrentQueueItem(
- @Nullable MediaController controller, long qid) {
- if (controller == null) {
- MediaDescription.Builder bob = new MediaDescription.Builder();
- bob.setTitle(UNKNOWN_TITLE);
- return new QueueItem(bob.build(), qid);
- }
-
- MediaMetadata metadata = controller.getMetadata();
- if (metadata == null) {
- Log.w(TAG, "Controller has no metadata!? Making an empty one");
- metadata = (new MediaMetadata.Builder()).build();
- }
-
- MediaDescription.Builder bob = new MediaDescription.Builder();
- MediaDescription desc = metadata.getDescription();
-
- // set the simple ones that MediaMetadata builds for us
- bob.setMediaId(desc.getMediaId());
- bob.setTitle(desc.getTitle());
- bob.setSubtitle(desc.getSubtitle());
- bob.setDescription(desc.getDescription());
- // fill the ones that we use later
- bob.setExtras(fillBundle(metadata, desc.getExtras()));
-
- // build queue item with the new metadata
- desc = bob.build();
- return new QueueItem(desc, qid);
}
private Bundle fillBundle(MediaMetadata metadata, Bundle currentExtras) {
@@ -211,15 +188,10 @@
return bundle;
}
- void updateNowPlayingList(@Nullable MediaController mediaController) {
- mNowPlayingListUpdated = true;
- getNowPlayingList(mediaController);
- }
-
/* Instructs media player to play particular media item */
void playItem(byte[] bdaddr, byte[] uid, @Nullable MediaController mediaController) {
long qid = ByteBuffer.wrap(uid).getLong();
- List<MediaSession.QueueItem> items = getNowPlayingList(mediaController);
+ List<MediaSession.QueueItem> items = updateNowPlayingList(mediaController);
if (mediaController == null) {
Log.e(TAG, "No mediaController when PlayItem " + qid + " requested");
@@ -250,7 +222,7 @@
}
void getTotalNumOfItems(byte[] bdaddr, @Nullable MediaController mediaController) {
- List<MediaSession.QueueItem> items = getNowPlayingList(mediaController);
+ List<MediaSession.QueueItem> items = updateNowPlayingList(mediaController);
if (DEBUG) Log.d(TAG, "getTotalNumOfItems: " + items.size() + " items.");
mMediaInterface.getTotalNumOfItemsRsp(bdaddr, AvrcpConstants.RSP_NO_ERROR, 0, items.size());
}
diff --git a/src/com/android/bluetooth/avrcp/Avrcp.java b/src/com/android/bluetooth/avrcp/Avrcp.java
index 274c10b..a00502c 100644
--- a/src/com/android/bluetooth/avrcp/Avrcp.java
+++ b/src/com/android/bluetooth/avrcp/Avrcp.java
@@ -33,6 +33,7 @@
import android.content.res.Resources;
import android.content.SharedPreferences;
import android.media.AudioManager;
+import android.media.AudioPlaybackConfiguration;
import android.media.MediaDescription;
import android.media.MediaMetadata;
import android.media.browse.MediaBrowser;
@@ -78,6 +79,8 @@
private Context mContext;
private final AudioManager mAudioManager;
private AvrcpMessageHandler mHandler;
+ private Handler mAudioManagerPlaybackHandler;
+ private AudioManagerPlaybackListener mAudioManagerPlaybackCb;
private MediaSessionManager mMediaSessionManager;
private @Nullable MediaController mMediaController;
private MediaControllerListener mMediaControllerCb;
@@ -87,6 +90,7 @@
private int mTransportControlFlags;
private @NonNull PlaybackState mCurrentPlayState;
private int mA2dpState;
+ private boolean mAudioManagerIsPlaying;
private int mPlayStatusChangedNT;
private byte mReportedPlayStatus;
private int mTrackChangedNT;
@@ -240,6 +244,7 @@
mCurrentPlayState = new PlaybackState.Builder().setState(PlaybackState.STATE_NONE, -1L, 0.0f).build();
mReportedPlayStatus = PLAYSTATUS_ERROR;
mA2dpState = BluetoothA2dp.STATE_NOT_PLAYING;
+ mAudioManagerIsPlaying = false;
mPlayStatusChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
mTrackChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
mPlayPosChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
@@ -279,6 +284,13 @@
Resources resources = context.getResources();
if (resources != null) {
mAbsVolThreshold = resources.getInteger(R.integer.a2dp_absolute_volume_initial_threshold);
+
+ // Update the threshold if the threshold_percent is valid
+ int threshold_percent =
+ resources.getInteger(R.integer.a2dp_absolute_volume_initial_threshold_percent);
+ if (threshold_percent >= 0 && threshold_percent <= 100) {
+ mAbsVolThreshold = (threshold_percent * mAudioStreamMax) / 100;
+ }
}
// Register for package removal intent broadcasts for media button receiver persistence
@@ -300,6 +312,8 @@
thread.start();
Looper looper = thread.getLooper();
mHandler = new AvrcpMessageHandler(looper);
+ mAudioManagerPlaybackHandler = new Handler(looper);
+ mAudioManagerPlaybackCb = new AudioManagerPlaybackListener();
mMediaControllerCb = new MediaControllerListener();
mAvrcpMediaRsp = new AvrcpMediaRsp();
mMediaPlayerInfoList = new TreeMap<Integer, MediaPlayerInfo>();
@@ -329,6 +343,9 @@
// initialize browsable player list and build media player list
buildBrowsablePlayerList();
}
+
+ mAudioManager.registerAudioPlaybackCallback(
+ mAudioManagerPlaybackCb, mAudioManagerPlaybackHandler);
}
public static Avrcp make(Context context) {
@@ -340,18 +357,23 @@
public synchronized void doQuit() {
if (DEBUG) Log.d(TAG, "doQuit");
+ if (mAudioManager != null) {
+ mAudioManager.unregisterAudioPlaybackCallback(mAudioManagerPlaybackCb);
+ }
if (mMediaController != null) mMediaController.unregisterCallback(mMediaControllerCb);
if (mMediaSessionManager != null) {
mMediaSessionManager.setCallback(null, null);
mMediaSessionManager.removeOnActiveSessionsChangedListener(mActiveSessionListener);
}
+ mAudioManagerPlaybackHandler.removeCallbacksAndMessages(null);
mHandler.removeCallbacksAndMessages(null);
Looper looper = mHandler.getLooper();
if (looper != null) {
looper.quit();
}
+ mAudioManagerPlaybackHandler = null;
mHandler = null;
mContext.unregisterReceiver(mAvrcpReceiver);
mContext.unregisterReceiver(mBootReceiver);
@@ -367,6 +389,30 @@
mVolumeMapping.clear();
}
+ private class AudioManagerPlaybackListener extends AudioManager.AudioPlaybackCallback {
+ @Override
+ public void onPlaybackConfigChanged(List<AudioPlaybackConfiguration> configs) {
+ super.onPlaybackConfigChanged(configs);
+ boolean isPlaying = false;
+ for (AudioPlaybackConfiguration config : configs) {
+ if (DEBUG) {
+ Log.d(TAG,
+ "AudioManager Player: "
+ + AudioPlaybackConfiguration.toLogFriendlyString(config));
+ }
+ if (config.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
+ isPlaying = true;
+ break;
+ }
+ }
+ if (DEBUG) Log.d(TAG, "AudioManager isPlaying: " + isPlaying);
+ if (mAudioManagerIsPlaying != isPlaying) {
+ mAudioManagerIsPlaying = isPlaying;
+ updateCurrentMediaState();
+ }
+ }
+ }
+
private class MediaControllerListener extends MediaController.Callback {
@Override
public void onMetadataChanged(MediaMetadata metadata) {
@@ -413,10 +459,13 @@
case MSG_NATIVE_REQ_GET_RC_FEATURES:
{
String address = (String) msg.obj;
- if (DEBUG) Log.v(TAG, "MSG_NATIVE_REQ_GET_RC_FEATURES: address="+address+
- ", features="+msg.arg1);
mFeatures = msg.arg1;
mFeatures = modifyRcFeatureFromBlacklist(mFeatures, address);
+ if (DEBUG) {
+ Log.v(TAG,
+ "MSG_NATIVE_REQ_GET_RC_FEATURES: address=" + address
+ + ", features=" + msg.arg1 + ", mFeatures=" + mFeatures);
+ }
mAudioManager.avrcpSupportsAbsoluteVolume(address, isAbsoluteVolumeSupported());
mLastLocalVolume = -1;
mRemoteVolume = -1;
@@ -797,10 +846,22 @@
if (controllerState != null) {
newState = controllerState;
- } else if (mAudioManager != null && mAudioManager.isMusicActive()) {
- // Use A2DP state if we don't have a state from MediaControlller
+ }
+ // Use the AudioManager to update the playback state.
+ // NOTE: We cannot use the
+ // (mA2dpState == BluetoothA2dp.STATE_PLAYING)
+ // check, because after Pause, the A2DP state remains in
+ // STATE_PLAYING for 3 more seconds.
+ // As a result of that, if we pause the music, on carkits the
+ // Play status indicator will continue to display "Playing"
+ // for 3 more seconds which can be confusing.
+ if ((mAudioManagerIsPlaying && newState.getState() != PlaybackState.STATE_PLAYING)
+ || (controllerState == null && mAudioManager != null
+ && mAudioManager.isMusicActive())) {
+ // Use AudioManager playback state if we don't have the state
+ // from MediaControlller
PlaybackState.Builder builder = new PlaybackState.Builder();
- if (mA2dpState == BluetoothA2dp.STATE_PLAYING) {
+ if (mAudioManagerIsPlaying) {
builder.setState(PlaybackState.STATE_PLAYING,
PlaybackState.PLAYBACK_POSITION_UNKNOWN, 1.0f);
} else {
@@ -1016,22 +1077,6 @@
mAddressedMediaPlayer.updateNowPlayingList(mMediaController);
}
- if ((newQueueId == -1 || newQueueId != mLastQueueId)
- && currentAttributes.equals(mMediaAttributes)
- && newPlayStatus == PLAYSTATUS_PLAYING
- && mReportedPlayStatus == PLAYSTATUS_STOPPED) {
- // Most carkits like seeing the track changed before the
- // playback state changed, but some controllers are slow
- // to update their metadata. Hold of on sending the playback state
- // update until after we know the current metadata is up to date
- // and track changed has been sent. This was seen on BMW carkits
- Log.i(TAG,
- "Waiting for metadata update to send track changed: " + newQueueId + " : "
- + currentAttributes + " : " + mMediaAttributes);
-
- return;
- }
-
// Notify track changed if:
// - The CT is registered for the notification
// - Queue ID is UNKNOWN and MediaMetadata is different
@@ -1050,9 +1095,11 @@
}
// still send the updated play state if the playback state is none or buffering
- Log.e(TAG, "play status change " + mReportedPlayStatus + "➡" + newPlayStatus);
+ Log.e(TAG,
+ "play status change " + mReportedPlayStatus + "➡" + newPlayStatus
+ + " mPlayStatusChangedNT: " + mPlayStatusChangedNT);
if (mPlayStatusChangedNT == AvrcpConstants.NOTIFICATION_TYPE_INTERIM
- && (mReportedPlayStatus != newPlayStatus)) {
+ || (mReportedPlayStatus != newPlayStatus)) {
sendPlaybackStatus(AvrcpConstants.NOTIFICATION_TYPE_CHANGED, newPlayStatus);
}
@@ -2364,6 +2411,20 @@
ProfileService.println(sb, " " + log);
}
}
+
+ // Print the blacklisted devices (for absolute volume control)
+ SharedPreferences pref =
+ mContext.getSharedPreferences(ABSOLUTE_VOLUME_BLACKLIST, Context.MODE_PRIVATE);
+ Map<String, ?> allKeys = pref.getAll();
+ ProfileService.println(sb, "");
+ ProfileService.println(sb, "Runtime Blacklisted Devices (absolute volume):");
+ if (allKeys.isEmpty()) {
+ ProfileService.println(sb, " None");
+ } else {
+ for (String key : allKeys.keySet()) {
+ ProfileService.println(sb, " " + key);
+ }
+ }
}
public class AvrcpBrowseManager {
diff --git a/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java b/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
index b0c1926..7ff0a25 100644
--- a/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
+++ b/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
@@ -435,7 +435,7 @@
public synchronized boolean getChildren(
BluetoothDevice device, String parentMediaId, int start, int items) {
if (DBG) {
- Log.d(TAG, "getChildrent device = " + device + " parent " + parentMediaId);
+ Log.d(TAG, "getChildren device = " + device + " parent " + parentMediaId);
}
if (device == null) {
diff --git a/src/com/android/bluetooth/btservice/AdapterProperties.java b/src/com/android/bluetooth/btservice/AdapterProperties.java
index b65113c..07b7bfe 100644
--- a/src/com/android/bluetooth/btservice/AdapterProperties.java
+++ b/src/com/android/bluetooth/btservice/AdapterProperties.java
@@ -65,8 +65,8 @@
private CopyOnWriteArrayList<BluetoothDevice> mBondedDevices = new CopyOnWriteArrayList<BluetoothDevice>();
private int mProfilesConnecting, mProfilesConnected, mProfilesDisconnecting;
- private HashMap<Integer, Pair<Integer, Integer>> mProfileConnectionState;
-
+ private final HashMap<Integer, Pair<Integer, Integer>> mProfileConnectionState =
+ new HashMap<>();
private volatile int mConnectionState = BluetoothAdapter.STATE_DISCONNECTED;
private volatile int mState = BluetoothAdapter.STATE_OFF;
@@ -93,35 +93,55 @@
private boolean mIsLePeriodicAdvertisingSupported;
private int mLeMaximumAdvertisingDataLength;
+ private boolean mReceiverRegistered;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- Log.d(TAG, "Received intent " + intent);
String action = intent.getAction();
- if (BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.HEADSET, intent);
- } else if (BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.A2DP, intent);
- } else if (BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.HEADSET_CLIENT, intent);
- } else if (BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.A2DP_SINK, intent);
- } else if (BluetoothInputHost.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.INPUT_HOST, intent);
- } else if (BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.INPUT_DEVICE, intent);
- } else if (BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.AVRCP_CONTROLLER, intent);
- } else if (BluetoothPan.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.PAN, intent);
- } else if (BluetoothMap.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.MAP, intent);
- } else if (BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.MAP_CLIENT, intent);
- } else if (BluetoothSap.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.SAP, intent);
- } else if (BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.PBAP_CLIENT, intent);
+ if (action == null) {
+ Log.w(TAG, "Received intent with null action");
+ return;
+ }
+ switch (action) {
+ case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.HEADSET, intent);
+ break;
+ case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.A2DP, intent);
+ break;
+ case BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.HEADSET_CLIENT, intent);
+ break;
+ case BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.A2DP_SINK, intent);
+ break;
+ case BluetoothInputHost.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.INPUT_HOST, intent);
+ break;
+ case BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.INPUT_DEVICE, intent);
+ break;
+ case BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.AVRCP_CONTROLLER, intent);
+ break;
+ case BluetoothPan.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.PAN, intent);
+ break;
+ case BluetoothMap.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.MAP, intent);
+ break;
+ case BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.MAP_CLIENT, intent);
+ break;
+ case BluetoothSap.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.SAP, intent);
+ break;
+ case BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.PBAP_CLIENT, intent);
+ break;
+ default:
+ Log.w(TAG, "Received unknown intent " + intent);
+ break;
}
}
};
@@ -129,18 +149,14 @@
// Lock for all getters and setters.
// If finer grained locking is needer, more locks
// can be added here.
- private Object mObject = new Object();
+ private final Object mObject = new Object();
public AdapterProperties(AdapterService service) {
mService = service;
mAdapter = BluetoothAdapter.getDefaultAdapter();
}
public void init(RemoteDevices remoteDevices) {
- if (mProfileConnectionState ==null) {
- mProfileConnectionState = new HashMap<Integer, Pair<Integer, Integer>>();
- } else {
- mProfileConnectionState.clear();
- }
+ mProfileConnectionState.clear();
mRemoteDevices = remoteDevices;
IntentFilter filter = new IntentFilter();
@@ -156,17 +172,17 @@
filter.addAction(BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothSap.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED);
- filter.addAction(BluetoothDevice.ACTION_UUID);
mService.registerReceiver(mReceiver, filter);
+ mReceiverRegistered = true;
}
public void cleanup() {
mRemoteDevices = null;
- if (mProfileConnectionState != null) {
- mProfileConnectionState.clear();
- mProfileConnectionState = null;
+ mProfileConnectionState.clear();
+ if (mReceiverRegistered) {
+ mService.unregisterReceiver(mReceiver);
+ mReceiverRegistered = false;
}
- mService.unregisterReceiver(mReceiver);
mService = null;
mBondedDevices.clear();
}
@@ -228,18 +244,6 @@
}
/**
- * Set local adapter UUIDs.
- *
- * @param uuids the uuids to be set.
- */
- boolean setUuids(ParcelUuid[] uuids) {
- synchronized (mObject) {
- return mService.setAdapterPropertyNative(
- AbstractionLayer.BT_PROPERTY_UUIDS, Utils.uuidsToByteArray(uuids));
- }
- }
-
- /**
* @return the mAddress
*/
byte[] getAddress() {
@@ -377,8 +381,10 @@
// state changes.
void onBondStateChanged(BluetoothDevice device, int state)
{
- if(device == null)
+ if (device == null) {
+ Log.w(TAG, "onBondStateChanged, device is null");
return;
+ }
try {
byte[] addrByte = Utils.getByteAddress(device);
DeviceProperties prop = mRemoteDevices.getDeviceProperties(device);
@@ -401,7 +407,7 @@
}
}
catch(Exception ee) {
- Log.e(TAG, "Exception in onBondStateChanged : ", ee);
+ Log.w(TAG, "onBondStateChanged: Exception ", ee);
}
}
@@ -437,6 +443,14 @@
BluetoothDevice device = connIntent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int prevState = connIntent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1);
int state = connIntent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
+ Log.d(TAG,
+ "PROFILE_CONNECTION_STATE_CHANGE: profile=" + profile + ", device=" + device + ", "
+ + prevState + " -> " + state);
+ if (!isNormalStateTransition(prevState, state)) {
+ Log.w(TAG,
+ "PROFILE_CONNECTION_STATE_CHANGE: unexpected transition for profile=" + profile
+ + ", device=" + device + ", " + prevState + " -> " + state);
+ }
sendConnectionStateChange(device, profile, state, prevState);
}
void sendConnectionStateChange(BluetoothDevice device, int profile, int state, int prevState) {
@@ -446,8 +460,8 @@
// with the invalid state converted to -1 in the intent.
// Better to log an error and not send an intent with
// invalid contents or set mAdapterConnectionState to -1.
- errorLog("Error in sendConnectionStateChange: "
- + "prevState " + prevState + " state " + state);
+ errorLog("sendConnectionStateChange: invalid state transition " + prevState + " -> "
+ + state);
return;
}
@@ -455,19 +469,25 @@
updateProfileConnectionState(profile, state, prevState);
if (updateCountersAndCheckForConnectionStateChange(state, prevState)) {
- setConnectionState(state);
+ int newAdapterState = convertToAdapterState(state);
+ int prevAdapterState = convertToAdapterState(prevState);
+ setConnectionState(newAdapterState);
Intent intent = new Intent(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.putExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
- convertToAdapterState(state));
- intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE,
- convertToAdapterState(prevState));
+ intent.putExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, newAdapterState);
+ intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE, prevAdapterState);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- mService.sendBroadcastAsUser(intent, UserHandle.ALL,
- mService.BLUETOOTH_PERM);
- Log.d(TAG, "CONNECTION_STATE_CHANGE: " + device + ": "
- + prevState + " -> " + state);
+ Log.d(TAG,
+ "ADAPTER_CONNECTION_STATE_CHANGE: " + device + ": " + prevAdapterState
+ + " -> " + newAdapterState);
+ if (!isNormalStateTransition(prevState, state)) {
+ Log.w(TAG,
+ "ADAPTER_CONNECTION_STATE_CHANGE: unexpected transition for profile="
+ + profile + ", device=" + device + ", " + prevState + " -> "
+ + state);
+ }
+ mService.sendBroadcastAsUser(intent, UserHandle.ALL, AdapterService.BLUETOOTH_PERM);
}
}
}
@@ -479,8 +499,7 @@
state == BluetoothProfile.STATE_DISCONNECTING);
}
-
- private int convertToAdapterState(int state) {
+ private static int convertToAdapterState(int state) {
switch (state) {
case BluetoothProfile.STATE_DISCONNECTED:
return BluetoothAdapter.STATE_DISCONNECTED;
@@ -491,22 +510,46 @@
case BluetoothProfile.STATE_CONNECTING:
return BluetoothAdapter.STATE_CONNECTING;
}
- Log.e(TAG, "Error in convertToAdapterState");
+ Log.e(TAG, "convertToAdapterState, unknow state " + state);
return -1;
}
+ private static boolean isNormalStateTransition(int prevState, int nextState) {
+ switch (prevState) {
+ case BluetoothProfile.STATE_DISCONNECTED:
+ return nextState == BluetoothProfile.STATE_CONNECTING;
+ case BluetoothProfile.STATE_CONNECTED:
+ return nextState == BluetoothProfile.STATE_DISCONNECTING;
+ case BluetoothProfile.STATE_DISCONNECTING:
+ case BluetoothProfile.STATE_CONNECTING:
+ return (nextState == BluetoothProfile.STATE_DISCONNECTED)
+ || (nextState == BluetoothProfile.STATE_CONNECTED);
+ default:
+ return false;
+ }
+ }
+
private boolean updateCountersAndCheckForConnectionStateChange(int state, int prevState) {
switch (prevState) {
case BluetoothProfile.STATE_CONNECTING:
- mProfilesConnecting--;
+ if (mProfilesConnecting > 0)
+ mProfilesConnecting--;
+ else
+ Log.e(TAG, "mProfilesConnecting " + mProfilesConnecting);
break;
case BluetoothProfile.STATE_CONNECTED:
- mProfilesConnected--;
+ if (mProfilesConnected > 0)
+ mProfilesConnected--;
+ else
+ Log.e(TAG, "mProfilesConnected " + mProfilesConnected);
break;
case BluetoothProfile.STATE_DISCONNECTING:
- mProfilesDisconnecting--;
+ if (mProfilesDisconnecting > 0)
+ mProfilesDisconnecting--;
+ else
+ Log.e(TAG, "mProfilesDisconnecting " + mProfilesDisconnecting);
break;
}
@@ -597,8 +640,8 @@
intent = new Intent(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_LOCAL_NAME, mName);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- mService.sendBroadcastAsUser(intent, UserHandle.ALL,
- mService.BLUETOOTH_PERM);
+ mService.sendBroadcastAsUser(
+ intent, UserHandle.ALL, AdapterService.BLUETOOTH_PERM);
debugLog("Name is: " + mName);
break;
case AbstractionLayer.BT_PROPERTY_BDADDR:
@@ -609,7 +652,7 @@
intent.putExtra(BluetoothAdapter.EXTRA_BLUETOOTH_ADDRESS, address);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mService.sendBroadcastAsUser(
- intent, UserHandle.ALL, mService.BLUETOOTH_PERM);
+ intent, UserHandle.ALL, AdapterService.BLUETOOTH_PERM);
break;
case AbstractionLayer.BT_PROPERTY_CLASS_OF_DEVICE:
mBluetoothClass = Utils.byteArrayToInt(val, 0);
@@ -617,11 +660,11 @@
break;
case AbstractionLayer.BT_PROPERTY_ADAPTER_SCAN_MODE:
int mode = Utils.byteArrayToInt(val, 0);
- mScanMode = mService.convertScanModeFromHal(mode);
+ mScanMode = AdapterService.convertScanModeFromHal(mode);
intent = new Intent(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_SCAN_MODE, mScanMode);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- mService.sendBroadcast(intent, mService.BLUETOOTH_PERM);
+ mService.sendBroadcast(intent, AdapterService.BLUETOOTH_PERM);
debugLog("Scan Mode:" + mScanMode);
if (mBluetoothDisabling) {
mBluetoothDisabling=false;
@@ -657,7 +700,7 @@
}
}
- void updateFeatureSupport(byte[] val) {
+ private void updateFeatureSupport(byte[] val) {
mVersSupported = ((0xFF & ((int)val[1])) << 8)
+ (0xFF & ((int)val[0]));
mNumOfAdvertisementInstancesSupported = (0xFF & ((int)val[3]));
@@ -712,12 +755,17 @@
}
void onBluetoothReady() {
- Log.d(TAG, "ScanMode = " + mScanMode );
- Log.d(TAG, "State = " + getState() );
+ debugLog("onBluetoothReady, state=" + getState() + ", ScanMode=" + mScanMode);
- // When BT is being turned on, all adapter properties will be sent in 1
- // callback. At this stage, set the scan mode.
synchronized (mObject) {
+ // Reset adapter and profile connection states
+ setConnectionState(BluetoothAdapter.STATE_DISCONNECTED);
+ mProfileConnectionState.clear();
+ mProfilesConnected = 0;
+ mProfilesConnecting = 0;
+ mProfilesDisconnecting = 0;
+ // When BT is being turned on, all adapter properties will be sent in 1
+ // callback. At this stage, set the scan mode.
if (getState() == BluetoothAdapter.STATE_TURNING_ON &&
mScanMode == BluetoothAdapter.SCAN_MODE_NONE) {
/* mDiscoverableTimeout is part of the
@@ -769,25 +817,25 @@
mDiscovering = false;
mDiscoveryEndMs = System.currentTimeMillis();
intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
- mService.sendBroadcast(intent, mService.BLUETOOTH_PERM);
+ mService.sendBroadcast(intent, AdapterService.BLUETOOTH_PERM);
} else if (state == AbstractionLayer.BT_DISCOVERY_STARTED) {
mDiscovering = true;
mDiscoveryEndMs = System.currentTimeMillis() + DEFAULT_DISCOVERY_TIMEOUT_MS;
intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
- mService.sendBroadcast(intent, mService.BLUETOOTH_PERM);
+ mService.sendBroadcast(intent, AdapterService.BLUETOOTH_PERM);
}
}
}
- private void infoLog(String msg) {
+ private static void infoLog(String msg) {
if (VDBG) Log.i(TAG, msg);
}
- private void debugLog(String msg) {
+ private static void debugLog(String msg) {
if (DBG) Log.d(TAG, msg);
}
- private void errorLog(String msg) {
+ private static void errorLog(String msg) {
Log.e(TAG, msg);
}
}
diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java
index b3fe737..a2a675f 100644
--- a/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/src/com/android/bluetooth/btservice/AdapterService.java
@@ -1499,6 +1499,7 @@
}
boolean startDiscovery() {
+ debugLog("startDiscovery");
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH ADMIN permission");
@@ -1506,6 +1507,7 @@
}
boolean cancelDiscovery() {
+ debugLog("cancelDiscovery");
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH ADMIN permission");
diff --git a/src/com/android/bluetooth/btservice/BondStateMachine.java b/src/com/android/bluetooth/btservice/BondStateMachine.java
index 336e916..d7dab6d 100644
--- a/src/com/android/bluetooth/btservice/BondStateMachine.java
+++ b/src/com/android/bluetooth/btservice/BondStateMachine.java
@@ -341,7 +341,8 @@
private void sendIntent(BluetoothDevice device, int newState, int reason) {
DeviceProperties devProp = mRemoteDevices.getDeviceProperties(device);
int oldState = BluetoothDevice.BOND_NONE;
- if (newState != BluetoothDevice.BOND_NONE && newState != BluetoothDevice.BOND_BONDING
+ if (newState != BluetoothDevice.BOND_NONE
+ && newState != BluetoothDevice.BOND_BONDING
&& newState != BluetoothDevice.BOND_BONDED) {
infoLog("Invalid bond state " + newState);
return;
@@ -364,11 +365,9 @@
mAdapterProperties.onBondStateChanged(device, newState);
- if (devProp != null
- && ((devProp.getDeviceType() == BluetoothDevice.DEVICE_TYPE_CLASSIC
- || devProp.getDeviceType() == BluetoothDevice.DEVICE_TYPE_DUAL)
- && newState == BluetoothDevice.BOND_BONDED
- && devProp.getUuids() == null)) {
+ if (devProp != null && ((devProp.getDeviceType() == BluetoothDevice.DEVICE_TYPE_CLASSIC
+ || devProp.getDeviceType() == BluetoothDevice.DEVICE_TYPE_DUAL)
+ && newState == BluetoothDevice.BOND_BONDED && devProp.getUuids() == null)) {
infoLog(device + " is bonded, wait for SDP complete to broadcast bonded intent");
if (!mPendingBondedDevices.contains(device)) {
mPendingBondedDevices.add(device);
diff --git a/src/com/android/bluetooth/btservice/PhonePolicy.java b/src/com/android/bluetooth/btservice/PhonePolicy.java
index 19817bf..b3ef04b 100644
--- a/src/com/android/bluetooth/btservice/PhonePolicy.java
+++ b/src/com/android/bluetooth/btservice/PhonePolicy.java
@@ -41,6 +41,7 @@
import com.android.bluetooth.pan.PanService;
import com.android.internal.R;
+import java.util.HashSet;
import java.util.List;
// Describes the phone policy
@@ -78,41 +79,53 @@
final private static int MESSAGE_CONNECT_OTHER_PROFILES = 3;
final private static int MESSAGE_ADAPTER_STATE_TURNED_ON = 4;
- public static final int PROFILE_CONN_CONNECTED = 1;
-
// Timeouts
final private static int CONNECT_OTHER_PROFILES_TIMEOUT = 6000; // 6s
final private AdapterService mAdapterService;
final private ServiceFactory mFactory;
final private Handler mHandler;
+ final private HashSet<BluetoothDevice> mHeadsetRetrySet = new HashSet<>();
+ final private HashSet<BluetoothDevice> mA2dpRetrySet = new HashSet<>();
// Broadcast receiver for all changes to states of various profiles
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- Log.d(TAG, "Received intent " + intent);
- if (BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) {
- mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED,
- BluetoothProfile.HEADSET,
- -1, // No-op argument
- intent)
- .sendToTarget();
- } else if (BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) {
- mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED,
- BluetoothProfile.A2DP,
- -1, // No-op argument
- intent)
- .sendToTarget();
- } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
- // Only pass the message on if the adapter has actually changed state from
- // non-ON to ON. NOTE: ON is the state depicting BREDR ON and not just BLE ON.
- int newState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
- if (newState == BluetoothAdapter.STATE_ON) {
- mHandler.obtainMessage(MESSAGE_ADAPTER_STATE_TURNED_ON).sendToTarget();
- }
- } else if (BluetoothDevice.ACTION_UUID.equals(intent.getAction())) {
- mHandler.obtainMessage(MESSAGE_PROFILE_INIT_PRIORITIES, intent).sendToTarget();
+ String action = intent.getAction();
+ if (action == null) {
+ errorLog("Received intent with null action");
+ return;
+ }
+ switch (action) {
+ case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED:
+ mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED,
+ BluetoothProfile.HEADSET,
+ -1, // No-op argument
+ intent)
+ .sendToTarget();
+ break;
+ case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
+ mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED,
+ BluetoothProfile.A2DP,
+ -1, // No-op argument
+ intent)
+ .sendToTarget();
+ break;
+ case BluetoothAdapter.ACTION_STATE_CHANGED:
+ // Only pass the message on if the adapter has actually changed state from
+ // non-ON to ON. NOTE: ON is the state depicting BREDR ON and not just BLE ON.
+ int newState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
+ if (newState == BluetoothAdapter.STATE_ON) {
+ mHandler.obtainMessage(MESSAGE_ADAPTER_STATE_TURNED_ON).sendToTarget();
+ }
+ break;
+ case BluetoothDevice.ACTION_UUID:
+ mHandler.obtainMessage(MESSAGE_PROFILE_INIT_PRIORITIES, intent).sendToTarget();
+ break;
+ default:
+ Log.e(TAG, "Received unexpected intent, action=" + action);
+ break;
}
}
};
@@ -132,17 +145,16 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_PROFILE_INIT_PRIORITIES: {
+ Intent intent = (Intent) msg.obj;
BluetoothDevice device =
- (BluetoothDevice) ((Intent) msg.obj)
- .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- Parcelable[] uuids =
- ((Intent) msg.obj).getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
-
- Log.d(TAG, "UUIDs on ACTION_UUID: " + uuids + " for device " + device);
+ intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+ Parcelable[] uuids = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
+ debugLog("Received ACTION_UUID for device " + device);
if (uuids != null) {
ParcelUuid[] uuidsToSend = new ParcelUuid[uuids.length];
for (int i = 0; i < uuidsToSend.length; i++) {
uuidsToSend[i] = (ParcelUuid) uuids[i];
+ debugLog("index=" + i + "uuid=" + uuidsToSend[i]);
}
processInitProfilePriorities(device, uuidsToSend);
}
@@ -165,6 +177,7 @@
case MESSAGE_ADAPTER_STATE_TURNED_ON:
// Call auto connect when adapter switches state to ON
+ resetStates();
autoConnect();
break;
}
@@ -182,6 +195,7 @@
}
protected void cleanup() {
mAdapterService.unregisterReceiver(mReceiver);
+ resetStates();
}
PhonePolicy(AdapterService service, ServiceFactory factory) {
@@ -192,7 +206,7 @@
// Policy implementation, all functions MUST be private
private void processInitProfilePriorities(BluetoothDevice device, ParcelUuid[] uuids) {
- debugLog("processInitProfilePriorities() - device " + device + " UUIDs " + uuids);
+ debugLog("processInitProfilePriorities() - device " + device);
HidService hidService = mFactory.getHidService();
A2dpService a2dpService = mFactory.getA2dpService();
HeadsetService headsetService = mFactory.getHeadsetService();
@@ -235,23 +249,35 @@
private void processProfileStateChanged(
BluetoothDevice device, int profileId, int nextState, int prevState) {
- // Profiles relevant to phones.
+ debugLog("processProfileStateChanged, device=" + device + ", profile=" + profileId + ", "
+ + prevState + " -> " + nextState);
if (((profileId == BluetoothProfile.A2DP) || (profileId == BluetoothProfile.HEADSET))
&& (nextState == BluetoothProfile.STATE_CONNECTED)) {
- debugLog("Profile connected id: " + profileId
- + " Schedule missing profile connection if any");
+ switch (profileId) {
+ case BluetoothProfile.A2DP:
+ mA2dpRetrySet.remove(device);
+ break;
+ case BluetoothProfile.HEADSET:
+ mHeadsetRetrySet.remove(device);
+ break;
+ }
connectOtherProfile(device);
setProfileAutoConnectionPriority(device, profileId);
}
}
+ private void resetStates() {
+ mHeadsetRetrySet.clear();
+ mA2dpRetrySet.clear();
+ }
+
private void autoConnect() {
if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) {
errorLog("autoConnect() - BT is not ON. Exiting autoConnect");
return;
}
- if (mAdapterService.isQuietModeEnabled() == false) {
+ if (!mAdapterService.isQuietModeEnabled()) {
debugLog("autoConnect() - Initiate auto connection on BT on...");
// Phone profiles.
autoConnectHeadset();
@@ -262,45 +288,48 @@
}
private void autoConnectHeadset() {
- HeadsetService hsService = mFactory.getHeadsetService();
+ final HeadsetService hsService = mFactory.getHeadsetService();
if (hsService == null) {
- errorLog("autoConnectHeadset() - service is null");
+ errorLog("autoConnectHeadset, service is null");
return;
}
-
- BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices();
+ final BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices();
if (bondedDevices == null) {
- errorLog("autoConnectHeadset() - devices are null");
+ errorLog("autoConnectHeadset, bondedDevices are null");
return;
}
-
- debugLog("autoConnectHeadset() - bondedDevices: " + bondedDevices);
for (BluetoothDevice device : bondedDevices) {
- debugLog("autoConnectHeadset() - attempt autoconnect with device " + device);
+ debugLog("autoConnectHeadset, attempt auto-connect with device " + device);
if (hsService.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT) {
- debugLog("autoConnectHeadset() - Connecting HFP with " + device.toString());
+ debugLog("autoConnectHeadset, Connecting HFP with " + device);
hsService.connect(device);
}
}
}
private void autoConnectA2dp() {
- A2dpService a2dpSservice = mFactory.getA2dpService();
- BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices();
- if ((bondedDevices == null) || (a2dpSservice == null)) {
+ final A2dpService a2dpService = mFactory.getA2dpService();
+ if (a2dpService == null) {
+ errorLog("autoConnectA2dp, service is null");
+ return;
+ }
+ final BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices();
+ if (bondedDevices == null) {
+ errorLog("autoConnectA2dp, bondedDevices are null");
return;
}
for (BluetoothDevice device : bondedDevices) {
- if (a2dpSservice.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT) {
- debugLog("autoConnectA2dp() - Connecting A2DP with " + device.toString());
- a2dpSservice.connect(device);
+ debugLog("autoConnectA2dp, attempt auto-connect with device " + device);
+ if (a2dpService.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT) {
+ debugLog("autoConnectA2dp, connecting A2DP with " + device);
+ a2dpService.connect(device);
}
}
}
- public void connectOtherProfile(BluetoothDevice device) {
- if ((mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES) == false)
- && (mAdapterService.isQuietModeEnabled() == false)) {
+ private void connectOtherProfile(BluetoothDevice device) {
+ if ((!mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES))
+ && (!mAdapterService.isQuietModeEnabled())) {
Message m = mHandler.obtainMessage(MESSAGE_CONNECT_OTHER_PROFILES);
m.obj = device;
mHandler.sendMessageDelayed(m, CONNECT_OTHER_PROFILES_TIMEOUT);
@@ -312,8 +341,9 @@
// connect to the device that initiated the connection. In the event that this function is
// invoked and there are no current bluetooth connections no new profiles will be connected.
private void processConnectOtherProfiles(BluetoothDevice device) {
- debugLog("processConnectOtherProfiles() - device " + device);
+ debugLog("processConnectOtherProfiles, device=" + device);
if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) {
+ warnLog("processConnectOtherProfiles, adapter is not ON " + mAdapterService.getState());
return;
}
HeadsetService hsService = mFactory.getHeadsetService();
@@ -338,29 +368,31 @@
allProfilesEmpty = allProfilesEmpty && panConnDevList.isEmpty();
}
- debugLog("processConnectOtherProfiles() - allProfilesEmpty " + allProfilesEmpty + " device "
- + device);
-
if (allProfilesEmpty) {
- // must have connected then disconnected, don't bother connecting others.
+ // considered as fully disconnected, don't bother connecting others.
+ debugLog("processConnectOtherProfiles, all profiles disconnected for " + device);
+ // reset retry status so that in the next round we can start retrying connections again
+ resetStates();
return;
}
if (hsService != null) {
- if (hsConnDevList.isEmpty()
+ if (hsConnDevList.isEmpty() && !mHeadsetRetrySet.contains(device)
&& (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)
&& (hsService.getConnectionState(device)
== BluetoothProfile.STATE_DISCONNECTED)) {
- debugLog("Retrying connection to HS with device " + device);
+ debugLog("Retrying connection to Headset with device " + device);
+ mHeadsetRetrySet.add(device);
hsService.connect(device);
}
}
if (a2dpService != null) {
- if (a2dpConnDevList.isEmpty()
+ if (a2dpConnDevList.isEmpty() && !mA2dpRetrySet.contains(device)
&& (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)
&& (a2dpService.getConnectionState(device)
== BluetoothProfile.STATE_DISCONNECTED)) {
debugLog("Retrying connection to A2DP with device " + device);
+ mA2dpRetrySet.add(device);
a2dpService.connect(device);
}
}
@@ -369,27 +401,20 @@
&& (panService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)
&& (panService.getConnectionState(device)
== BluetoothProfile.STATE_DISCONNECTED)) {
- debugLog("Retrying connection to HF with device " + device);
+ debugLog("Retrying connection to PAN with device " + device);
panService.connect(device);
}
}
}
- private void debugLog(String msg) {
- if (DBG) Log.d(TAG, msg);
- }
-
- private void errorLog(String msg) {
- Log.e(TAG, msg);
- }
-
- void setProfileAutoConnectionPriority(BluetoothDevice device, int profileId) {
+ private void setProfileAutoConnectionPriority(BluetoothDevice device, int profileId) {
switch (profileId) {
case BluetoothProfile.HEADSET:
HeadsetService hsService = mFactory.getHeadsetService();
- List<BluetoothDevice> deviceList = hsService.getConnectedDevices();
- if ((hsService != null) && (BluetoothProfile.PRIORITY_AUTO_CONNECT
- != hsService.getPriority(device))) {
+ if ((hsService != null)
+ && (BluetoothProfile.PRIORITY_AUTO_CONNECT
+ != hsService.getPriority(device))) {
+ List<BluetoothDevice> deviceList = hsService.getConnectedDevices();
adjustOtherHeadsetPriorities(hsService, deviceList);
hsService.setPriority(device, BluetoothProfile.PRIORITY_AUTO_CONNECT);
}
@@ -405,7 +430,7 @@
break;
default:
- Log.w(TAG, "Attempting to set Auto Connect priority on invalid profile");
+ Log.w(TAG, "Tried to set AutoConnect priority on invalid profile " + profileId);
break;
}
}
@@ -429,4 +454,16 @@
}
}
}
+
+ private static void debugLog(String msg) {
+ if (DBG) Log.d(TAG, msg);
+ }
+
+ private static void warnLog(String msg) {
+ Log.w(TAG, msg);
+ }
+
+ private static void errorLog(String msg) {
+ Log.e(TAG, msg);
+ }
}
diff --git a/src/com/android/bluetooth/gatt/AppScanStats.java b/src/com/android/bluetooth/gatt/AppScanStats.java
index 35bb51e..e65ad6b 100644
--- a/src/com/android/bluetooth/gatt/AppScanStats.java
+++ b/src/com/android/bluetooth/gatt/AppScanStats.java
@@ -50,6 +50,9 @@
class LastScan {
long duration;
+ long suspendDuration;
+ long suspendStartTime;
+ boolean isSuspended;
long timestamp;
boolean opportunistic;
boolean timeout;
@@ -67,6 +70,9 @@
this.filtered = filtered;
this.results = 0;
this.scannerId = scannerId;
+ this.suspendDuration = 0;
+ this.suspendStartTime = 0;
+ this.isSuspended = false;
}
}
@@ -90,6 +96,7 @@
long maxScanTime = 0;
long mScanStartTime = 0;
long mTotalScanTime = 0;
+ long mTotalSuspendTime = 0;
List<LastScan> lastScans = new ArrayList<LastScan>(NUM_SCAN_DURATIONS_KEPT);
HashMap<Integer, LastScan> ongoingScans = new HashMap<Integer, LastScan>();
long startTime = 0;
@@ -177,6 +184,10 @@
stopTime = SystemClock.elapsedRealtime();
long scanDuration = stopTime - scan.timestamp;
scan.duration = scanDuration;
+ if (scan.isSuspended) {
+ scan.suspendDuration += stopTime - scan.suspendStartTime;
+ mTotalSuspendTime += scan.suspendDuration;
+ }
ongoingScans.remove(scannerId);
if (lastScans.size() >= NUM_SCAN_DURATIONS_KEPT) {
lastScans.remove(0);
@@ -208,6 +219,26 @@
}
}
+ synchronized void recordScanSuspend(int scannerId) {
+ LastScan scan = getScanFromScannerId(scannerId);
+ if (scan == null || scan.isSuspended) {
+ return;
+ }
+ scan.suspendStartTime = SystemClock.elapsedRealtime();
+ scan.isSuspended = true;
+ }
+
+ synchronized void recordScanResume(int scannerId) {
+ LastScan scan = getScanFromScannerId(scannerId);
+ if (scan == null || !scan.isSuspended) {
+ return;
+ }
+ scan.isSuspended = false;
+ stopTime = SystemClock.elapsedRealtime();
+ scan.suspendDuration += stopTime - scan.suspendStartTime;
+ mTotalSuspendTime += scan.suspendDuration;
+ }
+
synchronized void setScanTimeout(int scannerId) {
if (!isScanning()) return;
@@ -299,6 +330,9 @@
maxScan + " / " +
avgScan + " / " +
totalScanTime + "\n");
+ if (mTotalSuspendTime != 0) {
+ sb.append(" Total time suspended : " + mTotalSuspendTime + "ms\n");
+ }
sb.append(" Total number of results : " +
results + "\n");
@@ -319,6 +353,10 @@
sb.append(scan.results + " results");
sb.append(" (" + scan.scannerId + ")");
sb.append("\n");
+ if (scan.suspendDuration != 0) {
+ sb.append(" └"
+ + " Suspended Time: " + scan.suspendDuration + "ms\n");
+ }
}
}
@@ -333,9 +371,16 @@
if (scan.background) sb.append("Back ");
if (scan.timeout) sb.append("Forced ");
if (scan.filtered) sb.append("Filter ");
+ if (scan.isSuspended) sb.append("Suspended ");
sb.append(scan.results + " results");
sb.append(" (" + scan.scannerId + ")");
sb.append("\n");
+ if (scan.suspendStartTime != 0) {
+ long duration = scan.suspendDuration
+ + (scan.isSuspended ? (elapsedRt - scan.suspendStartTime) : 0);
+ sb.append(" └"
+ + " Suspended Time: " + duration + "ms\n");
+ }
}
}
diff --git a/src/com/android/bluetooth/gatt/ContextMap.java b/src/com/android/bluetooth/gatt/ContextMap.java
index a9965db..13c46a8 100644
--- a/src/com/android/bluetooth/gatt/ContextMap.java
+++ b/src/com/android/bluetooth/gatt/ContextMap.java
@@ -86,6 +86,12 @@
/** Flag to signal that transport is congested */
Boolean isCongested = false;
+ /** Whether the calling app has location permission */
+ boolean hasLocationPermisson;
+
+ /** Whether the calling app has peers mac address permission */
+ boolean hasPeersMacAddressPermission;
+
/** Internal callback info queue, waiting to be send on congestion clear */
private List<CallbackInfo> congestionQueue = new ArrayList<CallbackInfo>();
@@ -151,7 +157,7 @@
/**
* Add an entry to the application context list.
*/
- void add(UUID uuid, WorkSource workSource, C callback, T info, GattService service) {
+ App add(UUID uuid, WorkSource workSource, C callback, T info, GattService service) {
int appUid = Binder.getCallingUid();
String appName = service.getPackageManager().getNameForUid(appUid);
if (appName == null) {
@@ -164,8 +170,10 @@
appScanStats = new AppScanStats(appName, workSource, this, service);
mAppScanStats.put(appUid, appScanStats);
}
- mApps.add(new App(uuid, callback, info, appName, appScanStats));
+ App app = new App(uuid, callback, info, appName, appScanStats);
+ mApps.add(app);
appScanStats.isRegistered = true;
+ return app;
}
}
diff --git a/src/com/android/bluetooth/gatt/GattService.java b/src/com/android/bluetooth/gatt/GattService.java
index 9117a7d..9a99bcd 100644
--- a/src/com/android/bluetooth/gatt/GattService.java
+++ b/src/com/android/bluetooth/gatt/GattService.java
@@ -37,6 +37,7 @@
import android.bluetooth.le.IScannerCallback;
import android.bluetooth.le.PeriodicAdvertisingParameters;
import android.bluetooth.le.ResultStorageDescriptor;
+import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
@@ -59,6 +60,7 @@
import com.android.bluetooth.util.NumberUtils;
import com.android.internal.annotations.VisibleForTesting;
+import java.security.Security;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -367,7 +369,8 @@
service.unregisterClient(clientIf);
}
- public void registerScanner(IScannerCallback callback, WorkSource workSource) {
+ public void registerScanner(IScannerCallback callback, WorkSource workSource)
+ throws RemoteException {
GattService service = getService();
if (service == null) return;
service.registerScanner(callback, workSource);
@@ -844,7 +847,7 @@
if (cbApp.callback != null) {
cbApp.linkToDeath(new ScannerDeathRecipient(scannerId));
} else {
- continuePiStartScan(scannerId, cbApp.info);
+ continuePiStartScan(scannerId, cbApp);
}
} else {
mScannerMap.remove(scannerId);
@@ -934,11 +937,17 @@
app.callback.onPhyUpdate(address, txPhy, rxPhy, status);
}
- void onClientPhyRead(int connId, int txPhy, int rxPhy, int status) throws RemoteException {
- if (DBG) Log.d(TAG, "onClientPhyRead() - connId=" + connId + ", status=" + status);
+ void onClientPhyRead(int clientIf, String address, int txPhy, int rxPhy, int status)
+ throws RemoteException {
+ if (DBG)
+ Log.d(TAG, "onClientPhyRead() - address=" + address + ", status=" + status
+ + ", clientIf=" + clientIf);
- String address = mClientMap.addressByConnId(connId);
- if (address == null) return;
+ Integer connId = mClientMap.connIdByAddress(clientIf, address);
+ if (connId == null) {
+ Log.d(TAG, "onClientPhyRead() - no connection to " + address);
+ return;
+ }
ClientMap.App app = mClientMap.getByConnId(connId);
if (app == null) return;
@@ -971,11 +980,15 @@
app.callback.onPhyUpdate(address, txPhy, rxPhy, status);
}
- void onServerPhyRead(int connId, int txPhy, int rxPhy, int status) throws RemoteException {
- if (DBG) Log.d(TAG, "onServerPhyRead() - connId=" + connId + ", status=" + status);
+ void onServerPhyRead(int serverIf, String address, int txPhy, int rxPhy, int status)
+ throws RemoteException {
+ if (DBG) Log.d(TAG, "onServerPhyRead() - address=" + address + ", status=" + status);
- String address = mServerMap.addressByConnId(connId);
- if (address == null) return;
+ Integer connId = mServerMap.connIdByAddress(serverIf, address);
+ if (connId == null) {
+ Log.d(TAG, "onServerPhyRead() - no connection to " + address);
+ return;
+ }
ServerMap.App app = mServerMap.getByConnId(connId);
if (app == null) return;
@@ -1548,7 +1561,7 @@
return deviceList;
}
- void registerScanner(IScannerCallback callback, WorkSource workSource) {
+ void registerScanner(IScannerCallback callback, WorkSource workSource) throws RemoteException {
enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
UUID uuid = UUID.randomUUID();
@@ -1559,6 +1572,14 @@
}
mScannerMap.add(uuid, workSource, callback, null, this);
+ AppScanStats app = mScannerMap.getAppScanStatsByUid(Binder.getCallingUid());
+ if (app != null && app.isScanningTooFrequently()
+ && checkCallingOrSelfPermission(BLUETOOTH_PRIVILEGED) != PERMISSION_GRANTED) {
+ Log.e(TAG, "App '" + app.appName + "' is scanning too frequently");
+ callback.onScannerRegistered(ScanCallback.SCAN_FAILED_SCANNING_TOO_FREQUENTLY, -1);
+ return;
+ }
+
mScanManager.registerScanner(uuid);
}
@@ -1584,17 +1605,9 @@
this);
scanClient.legacyForegroundApp = Utils.isLegacyForegroundApp(this, callingPackage);
- AppScanStats app = null;
- app = mScannerMap.getAppScanStatsById(scannerId);
-
+ AppScanStats app = mScannerMap.getAppScanStatsById(scannerId);
if (app != null) {
- if (app.isScanningTooFrequently() &&
- checkCallingOrSelfPermission(BLUETOOTH_PRIVILEGED) != PERMISSION_GRANTED) {
- Log.e(TAG, "App '" + app.appName + "' is scanning too frequently");
- return;
- }
scanClient.stats = app;
-
boolean isFilteredScan = (filters != null) && !filters.isEmpty();
app.recordScanStart(settings, isFilteredScan, scannerId);
}
@@ -1617,34 +1630,36 @@
piInfo.settings = settings;
piInfo.filters = filters;
piInfo.callingPackage = callingPackage;
- mScannerMap.add(uuid, null, null, piInfo, this);
+ ScannerMap.App app = mScannerMap.add(uuid, null, null, piInfo, this);
+ try {
+ app.hasLocationPermisson =
+ Utils.checkCallerHasLocationPermission(this, mAppOps, callingPackage);
+ } catch (SecurityException se) {
+ // No need to throw here. Just mark as not granted.
+ app.hasLocationPermisson = false;
+ }
+ try {
+ app.hasPeersMacAddressPermission = Utils.checkCallerHasPeersMacAddressPermission(this);
+ } catch (SecurityException se) {
+ // No need to throw here. Just mark as not granted.
+ app.hasPeersMacAddressPermission = false;
+ }
mScanManager.registerScanner(uuid);
}
- void continuePiStartScan(int scannerId, PendingIntentInfo piInfo) {
+ void continuePiStartScan(int scannerId, ScannerMap.App app) {
+ final PendingIntentInfo piInfo = app.info;
final ScanClient scanClient =
new ScanClient(scannerId, piInfo.settings, piInfo.filters, null);
- scanClient.hasLocationPermission =
- true; // Utils.checkCallerHasLocationPermission(this, mAppOps,
- // piInfo.callingPackage);
- scanClient.hasPeersMacAddressPermission =
- true; // Utils.checkCallerHasPeersMacAddressPermission(
- // this);
+ scanClient.hasLocationPermission = app.hasLocationPermisson;
+ scanClient.hasPeersMacAddressPermission = app.hasPeersMacAddressPermission;
scanClient.legacyForegroundApp = Utils.isLegacyForegroundApp(this, piInfo.callingPackage);
- AppScanStats app = null;
- app = mScannerMap.getAppScanStatsById(scannerId);
-
- if (app != null) {
- if (app.isScanningTooFrequently()
- && checkCallingOrSelfPermission(BLUETOOTH_PRIVILEGED) != PERMISSION_GRANTED) {
- Log.e(TAG, "App '" + app.appName + "' is scanning too frequently");
- return;
- }
- scanClient.stats = app;
-
+ AppScanStats scanStats = mScannerMap.getAppScanStatsById(scannerId);
+ if (scanStats != null) {
+ scanClient.stats = scanStats;
boolean isFilteredScan = (piInfo.filters != null) && !piInfo.filters.isEmpty();
- app.recordScanStart(piInfo.settings, isFilteredScan, scannerId);
+ scanStats.recordScanStart(piInfo.settings, isFilteredScan, scannerId);
}
mScanManager.startScan(scanClient);
@@ -1797,8 +1812,8 @@
enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
if (DBG) {
- Log.d(TAG, "clientConnect() - address=" + address + ", isDirect=" + isDirect
- + ", opportunistic=" + opportunistic + ", phy=" + phy);
+ Log.d(TAG, "clientConnect() - address=" + address + ", isDirect=" + isDirect +
+ ", opportunistic=" + opportunistic + ", phy=" + phy);
}
gattClientConnectNative(clientIf, address, isDirect, transport, opportunistic, phy);
}
@@ -1822,7 +1837,7 @@
}
if (DBG) Log.d(TAG, "clientSetPreferredPhy() - address=" + address + ", connId=" + connId);
- gattClientSetPreferredPhyNative(clientIf, connId, txPhy, rxPhy, phyOptions);
+ gattClientSetPreferredPhyNative(clientIf, address, txPhy, rxPhy, phyOptions);
}
void clientReadPhy(int clientIf, String address) {
@@ -1835,7 +1850,7 @@
}
if (DBG) Log.d(TAG, "clientReadPhy() - address=" + address + ", connId=" + connId);
- gattClientReadPhyNative(clientIf, connId);
+ gattClientReadPhyNative(clientIf, address);
}
int numHwTrackFiltersAvailable() {
@@ -2373,7 +2388,7 @@
}
if (DBG) Log.d(TAG, "serverSetPreferredPhy() - address=" + address + ", connId=" + connId);
- gattServerSetPreferredPhyNative(serverIf, connId, txPhy, rxPhy, phyOptions);
+ gattServerSetPreferredPhyNative(serverIf, address, txPhy, rxPhy, phyOptions);
}
void serverReadPhy(int serverIf, String address) {
@@ -2386,7 +2401,7 @@
}
if (DBG) Log.d(TAG, "serverReadPhy() - address=" + address + ", connId=" + connId);
- gattServerReadPhyNative(serverIf, connId);
+ gattServerReadPhyNative(serverIf, address);
}
void addService(int serverIf, BluetoothGattService service) {
@@ -2694,9 +2709,9 @@
int conn_id);
private native void gattClientSetPreferredPhyNative(
- int clientIf, int conn_id, int tx_phy, int rx_phy, int phy_options);
+ int clientIf, String address, int tx_phy, int rx_phy, int phy_options);
- private native void gattClientReadPhyNative(int clientIf, int conn_id);
+ private native void gattClientReadPhyNative(int clientIf, String address);
private native void gattClientRefreshNative(int clientIf, String address);
@@ -2746,9 +2761,9 @@
int conn_id);
private native void gattServerSetPreferredPhyNative(
- int clientIf, int conn_id, int tx_phy, int rx_phy, int phy_options);
+ int clientIf, String address, int tx_phy, int rx_phy, int phy_options);
- private native void gattServerReadPhyNative(int clientIf, int conn_id);
+ private native void gattServerReadPhyNative(int clientIf, String address);
private native void gattServerAddServiceNative(int server_if, List<GattDbElement> service);
diff --git a/src/com/android/bluetooth/gatt/ScanManager.java b/src/com/android/bluetooth/gatt/ScanManager.java
index f7dc9f3..65f4f6d 100644
--- a/src/com/android/bluetooth/gatt/ScanManager.java
+++ b/src/com/android/bluetooth/gatt/ScanManager.java
@@ -26,6 +26,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.hardware.display.DisplayManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
@@ -34,6 +35,7 @@
import android.os.ServiceManager;
import android.os.SystemClock;
import android.util.Log;
+import android.view.Display;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
@@ -69,7 +71,8 @@
private static final int MSG_STOP_BLE_SCAN = 1;
private static final int MSG_FLUSH_BATCH_RESULTS = 2;
private static final int MSG_SCAN_TIMEOUT = 3;
-
+ private static final int MSG_SUSPEND_SCANS = 4;
+ private static final int MSG_RESUME_SCANS = 5;
private static final String ACTION_REFRESH_BATCHED_SCAN =
"com.android.bluetooth.gatt.REFRESH_BATCHED_SCAN";
@@ -89,28 +92,42 @@
private Set<ScanClient> mRegularScanClients;
private Set<ScanClient> mBatchClients;
+ private Set<ScanClient> mSuspendedScanClients;
private CountDownLatch mLatch;
+ private DisplayManager mDm;
+
ScanManager(GattService service) {
mRegularScanClients = Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
mBatchClients = Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
+ mSuspendedScanClients =
+ Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
mService = service;
mScanNative = new ScanNative();
curUsedTrackableAdvertisements = 0;
+ mDm = (DisplayManager) mService.getSystemService(Context.DISPLAY_SERVICE);
}
void start() {
HandlerThread thread = new HandlerThread("BluetoothScanManager");
thread.start();
mHandler = new ClientHandler(thread.getLooper());
+ if (mDm != null) {
+ mDm.registerDisplayListener(mDisplayListener, null);
+ }
}
void cleanup() {
mRegularScanClients.clear();
mBatchClients.clear();
+ mSuspendedScanClients.clear();
mScanNative.cleanup();
+ if (mDm != null) {
+ mDm.unregisterDisplayListener(mDisplayListener);
+ }
+
if (mHandler != null) {
// Shut down the thread
mHandler.removeCallbacksAndMessages(null);
@@ -215,6 +232,12 @@
case MSG_SCAN_TIMEOUT:
mScanNative.regularScanTimeout(client);
break;
+ case MSG_SUSPEND_SCANS:
+ handleSuspendScans();
+ break;
+ case MSG_RESUME_SCANS:
+ handleResumeScans();
+ break;
default:
// Shouldn't happen.
Log.e(TAG, "received an unkown message : " + msg.what);
@@ -223,6 +246,7 @@
void handleStartScan(ScanClient client) {
Utils.enforceAdminPermission(mService);
+ boolean isFiltered = (client.filters != null) && !client.filters.isEmpty();
if (DBG) Log.d(TAG, "handling starting scan");
if (!isScanSupported(client)) {
@@ -234,6 +258,15 @@
Log.e(TAG, "Scan already started");
return;
}
+
+ if (!mScanNative.isOpportunisticScanClient(client) && !isScreenOn() && !isFiltered) {
+ Log.e(TAG,
+ "Cannot start unfiltered scan in screen-off. This scan will be resumed later: "
+ + client.scannerId);
+ mSuspendedScanClients.add(client);
+ return;
+ }
+
// Begin scan operations.
if (isBatchClient(client)) {
mBatchClients.add(client);
@@ -258,6 +291,10 @@
Utils.enforceAdminPermission(mService);
if (client == null) return;
+ if (mSuspendedScanClients.contains(client)) {
+ mSuspendedScanClients.remove(client);
+ }
+
if (mRegularScanClients.contains(client)) {
mScanNative.stopRegularScan(client);
@@ -305,6 +342,30 @@
return settings.getCallbackType() == ScanSettings.CALLBACK_TYPE_ALL_MATCHES &&
settings.getReportDelayMillis() == 0;
}
+
+ void handleSuspendScans() {
+ for (ScanClient client : mRegularScanClients) {
+ if (!mScanNative.isOpportunisticScanClient(client)
+ && (client.filters == null || client.filters.isEmpty())) {
+ /*Suspend unfiltered scans*/
+ if (client.stats != null) {
+ client.stats.recordScanSuspend(client.scannerId);
+ }
+ handleStopScan(client);
+ mSuspendedScanClients.add(client);
+ }
+ }
+ }
+
+ void handleResumeScans() {
+ for (ScanClient client : mSuspendedScanClients) {
+ if (client.stats != null) {
+ client.stats.recordScanResume(client.scannerId);
+ }
+ handleStartScan(client);
+ }
+ mSuspendedScanClients.clear();
+ }
}
/**
@@ -1163,4 +1224,38 @@
private native void gattClientReadScanReportsNative(int client_if, int scan_type);
}
+
+ private boolean isScreenOn() {
+ Display[] displays = mDm.getDisplays();
+
+ if (displays == null) {
+ return false;
+ }
+
+ for (Display display : displays) {
+ if (display.getState() == Display.STATE_ON) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private final DisplayManager.DisplayListener mDisplayListener =
+ new DisplayManager.DisplayListener() {
+ @Override
+ public void onDisplayAdded(int displayId) {}
+
+ @Override
+ public void onDisplayRemoved(int displayId) {}
+
+ @Override
+ public void onDisplayChanged(int displayId) {
+ if (isScreenOn()) {
+ sendMessage(MSG_RESUME_SCANS, null);
+ } else {
+ sendMessage(MSG_SUSPEND_SCANS, null);
+ }
+ }
+ };
}
diff --git a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
index 636ccf5..a7fa02a 100644
--- a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
+++ b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
@@ -812,31 +812,26 @@
break;
}
if (mConnectedDevicesList.size() >= max_hf_connections) {
- BluetoothDevice DisconnectConnectedDevice = null;
- IState CurrentAudioState = getCurrentState();
- Log.d(TAG, "Reach to max size, disconnect one of them first");
- /* TODO: Disconnect based on CoD */
- DisconnectConnectedDevice = mConnectedDevicesList.get(0);
-
+ BluetoothDevice disconnectDevice = mConnectedDevicesList.get(0);
+ Log.d(TAG, "Connected: Reach to max size, disconnect " + disconnectDevice);
broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,
BluetoothProfile.STATE_DISCONNECTED);
-
- if (!disconnectHfpNative(getByteAddress(DisconnectConnectedDevice))) {
+ if (disconnectHfpNative(getByteAddress(disconnectDevice))) {
+ broadcastConnectionState(disconnectDevice,
+ BluetoothProfile.STATE_DISCONNECTING,
+ BluetoothProfile.STATE_CONNECTED);
+ } else {
+ Log.w(TAG, "Connected: failed to disconnect " + disconnectDevice);
broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
BluetoothProfile.STATE_CONNECTING);
break;
- } else {
- broadcastConnectionState(DisconnectConnectedDevice,
- BluetoothProfile.STATE_DISCONNECTING,
- BluetoothProfile.STATE_CONNECTED);
}
-
synchronized (HeadsetStateMachine.this) {
mTargetDevice = device;
if (max_hf_connections == 1) {
transitionTo(mPending);
} else {
- mMultiDisconnectDevice = DisconnectConnectedDevice;
+ mMultiDisconnectDevice = disconnectDevice;
transitionTo(mMultiHFPending);
}
}
@@ -1123,9 +1118,9 @@
mAudioState = BluetoothHeadset.STATE_AUDIO_CONNECTED;
setAudioParameters(device); /*Set proper Audio Paramters.*/
mAudioManager.setBluetoothScoOn(true);
+ mActiveScoDevice = device;
broadcastAudioState(device, BluetoothHeadset.STATE_AUDIO_CONNECTED,
BluetoothHeadset.STATE_AUDIO_CONNECTING);
- mActiveScoDevice = device;
transitionTo(mAudioOn);
break;
case HeadsetHalConstants.AUDIO_STATE_CONNECTING:
@@ -1188,42 +1183,39 @@
deferMessage(obtainMessage(DISCONNECT, mCurrentDevice));
deferMessage(obtainMessage(CONNECT, device));
if (disconnectAudioNative(getByteAddress(mCurrentDevice))) {
- Log.d(TAG, "Disconnecting SCO audio for device=" + mCurrentDevice);
+ Log.d(TAG, "AudioOn: disconnecting SCO, device=" + mCurrentDevice);
} else {
- Log.e(TAG, "disconnectAudioNative failed");
+ Log.e(TAG, "AudioOn: disconnect SCO failed, device=" + mCurrentDevice);
}
break;
}
if (mConnectedDevicesList.size() >= max_hf_connections) {
- BluetoothDevice DisconnectConnectedDevice = null;
- IState CurrentAudioState = getCurrentState();
- Log.d(TAG, "Reach to max size, disconnect "
- + "one of them first");
- DisconnectConnectedDevice = mConnectedDevicesList.get(0);
+ BluetoothDevice disconnectDevice = mConnectedDevicesList.get(0);
+ Log.d(TAG, "AudioOn: Reach to max size, disconnect " + disconnectDevice);
- if (mActiveScoDevice.equals(DisconnectConnectedDevice)) {
- DisconnectConnectedDevice = mConnectedDevicesList.get(1);
+ if (mActiveScoDevice.equals(disconnectDevice)) {
+ disconnectDevice = mConnectedDevicesList.get(1);
}
broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,
BluetoothProfile.STATE_DISCONNECTED);
- if (!disconnectHfpNative(getByteAddress(DisconnectConnectedDevice))) {
+ if (disconnectHfpNative(getByteAddress(disconnectDevice))) {
+ broadcastConnectionState(disconnectDevice,
+ BluetoothProfile.STATE_DISCONNECTING,
+ BluetoothProfile.STATE_CONNECTED);
+ } else {
+ Log.e(TAG, "AudioOn: Failed to disconnect " + disconnectDevice);
broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
BluetoothProfile.STATE_CONNECTING);
break;
- } else {
- broadcastConnectionState(DisconnectConnectedDevice,
- BluetoothProfile.STATE_DISCONNECTING,
- BluetoothProfile.STATE_CONNECTED);
}
synchronized (HeadsetStateMachine.this) {
mTargetDevice = device;
- mMultiDisconnectDevice = DisconnectConnectedDevice;
+ mMultiDisconnectDevice = disconnectDevice;
transitionTo(mMultiHFPending);
- DisconnectConnectedDevice = null;
}
} else if (mConnectedDevicesList.size() < max_hf_connections) {
broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,
@@ -2100,7 +2092,7 @@
sco disconnect issued in AudioOn state. This was causing a mismatch in the
Incall screen UI. */
- if (getCurrentState() == mAudioOn && mCurrentDevice.equals(device)
+ if (mActiveScoDevice != null && mActiveScoDevice.equals(device)
&& mAudioState != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
return true;
}
@@ -2110,6 +2102,7 @@
public void setAudioRouteAllowed(boolean allowed) {
mAudioRouteAllowed = allowed;
+ setScoAllowedNative(allowed);
}
public boolean getAudioRouteAllowed() {
@@ -3463,4 +3456,5 @@
private native boolean phoneStateChangeNative(
int numActive, int numHeld, int callState, String number, int type);
private native boolean configureWBSNative(byte[] address, int condec_config);
+ private native boolean setScoAllowedNative(boolean value);
}
diff --git a/src/com/android/bluetooth/hfpclient/HeadsetClientService.java b/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
index ef5a12f..089f4a6 100644
--- a/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
+++ b/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
@@ -162,16 +162,30 @@
// ({@link HeadsetClientStateMachine#SET_SPEAKER_VOLUME} in
// {@link HeadsetClientStateMachine} for details.
if (action.equals(AudioManager.VOLUME_CHANGED_ACTION)) {
- Log.d(TAG, "Volume changed for stream: " +
- intent.getExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE));
+ if (DBG) {
+ Log.d(TAG,
+ "Volume changed for stream: "
+ + intent.getExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE));
+ }
int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
if (streamType == AudioManager.STREAM_VOICE_CALL) {
int streamValue = intent
.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
int hfVol = HeadsetClientStateMachine.amToHfVol(streamValue);
- Log.d(TAG, "Setting volume to audio manager: " + streamValue + " hands free: "
- + hfVol);
+ if (DBG) {
+ Log.d(TAG,
+ "Setting volume to audio manager: " + streamValue
+ + " hands free: " + hfVol);
+ }
mAudioManager.setParameters("hfp_volume=" + hfVol);
+ synchronized (this) {
+ for (HeadsetClientStateMachine sm : mStateMachineMap.values()) {
+ if (sm != null) {
+ sm.sendMessage(
+ HeadsetClientStateMachine.SET_SPEAKER_VOLUME, streamValue);
+ }
+ }
+ }
}
}
}
@@ -646,6 +660,25 @@
boolean acceptCall(BluetoothDevice device, int flag) {
enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ /* Phonecalls from a single device are supported, hang up any calls on the other phone */
+ synchronized (this) {
+ for (Map.Entry<BluetoothDevice, HeadsetClientStateMachine> entry :
+ mStateMachineMap.entrySet()) {
+ if (entry.getValue() == null || entry.getKey().equals(device)) {
+ continue;
+ }
+ int connectionState = entry.getValue().getConnectionState(entry.getKey());
+ if (DBG) {
+ Log.d(TAG, "Accepting a call on device " + device
+ + ". Possibly disconnecting on " + entry.getValue());
+ }
+ if (connectionState == BluetoothProfile.STATE_CONNECTED) {
+ entry.getValue()
+ .obtainMessage(HeadsetClientStateMachine.TERMINATE_CALL)
+ .sendToTarget();
+ }
+ }
+ }
HeadsetClientStateMachine sm = getStateMachine(device);
if (sm == null) {
Log.e(TAG, "Cannot allocate SM for device " + device);
@@ -653,8 +686,7 @@
}
int connectionState = sm.getConnectionState(device);
- if (connectionState != BluetoothProfile.STATE_CONNECTED &&
- connectionState != BluetoothProfile.STATE_CONNECTING) {
+ if (connectionState != BluetoothProfile.STATE_CONNECTED) {
return false;
}
Message msg = sm.obtainMessage(HeadsetClientStateMachine.ACCEPT_CALL);
@@ -872,19 +904,22 @@
return sm;
}
- // Check if any of the state machines are currently holding the SCO audio stream
- // This function is *only* called from the SMs which are themselves run the same thread and
- // hence we do not need synchronization here
- boolean isScoAvailable() {
- for (BluetoothDevice bd : mStateMachineMap.keySet()) {
- HeadsetClientStateMachine sm = mStateMachineMap.get(bd);
- int audioState = sm.getAudioState(bd);
- if (audioState != BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED) {
- Log.w(TAG, "Device " + bd + " audio state " + audioState + " not disconnected");
- return false;
+ // Check if any of the state machines have routed the SCO audio stream.
+ synchronized boolean isScoRouted() {
+ for (Map.Entry<BluetoothDevice, HeadsetClientStateMachine> entry :
+ mStateMachineMap.entrySet()) {
+ if (entry.getValue() != null) {
+ int audioState = entry.getValue().getAudioState(entry.getKey());
+ if (audioState == BluetoothHeadsetClient.STATE_AUDIO_CONNECTED) {
+ if (DBG) {
+ Log.d(TAG, "Device " + entry.getKey() + " audio state " + audioState
+ + " Connected");
+ }
+ return true;
+ }
}
}
- return true;
+ return false;
}
@Override
diff --git a/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java b/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
index 632789a..9ff30f7 100755
--- a/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
+++ b/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
@@ -104,6 +104,8 @@
// Timeouts.
static final int CONNECTING_TIMEOUT_MS = 10000; // 10s
+ static final int ROUTING_DELAY_MS = 250;
+ static final int SCO_DISCONNECT_TIMEOUT_MS = 750;
static final int MAX_HFP_SCO_VOICE_CALL_VOLUME = 15; // HFP 1.5 spec.
static final int MIN_HFP_SCO_VOICE_CALL_VOLUME = 1; // HFP 1.5 spec.
@@ -112,6 +114,9 @@
private long OUTGOING_TIMEOUT_MILLI = 10 * 1000; // 10 seconds
private long QUERY_CURRENT_CALLS_WAIT_MILLIS = 2 * 1000; // 2 seconds
+ // Keep track of audio routing across all devices.
+ private static boolean sAudioIsRouted = true;
+
private final Disconnected mDisconnected;
private final Connecting mConnecting;
private final Connected mConnected;
@@ -145,7 +150,7 @@
// indicator
private Pair<Integer, Object> mPendingAction;
- private final AudioManager mAudioManager;
+ private static AudioManager sAudioManager;
private int mAudioState;
private boolean mAudioWbs;
private final BluetoothAdapter mAdapter;
@@ -460,6 +465,8 @@
action = HeadsetClientHalConstants.CALL_ACTION_CHLD_1;
} else if (getCall(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) != null) {
action = HeadsetClientHalConstants.CALL_ACTION_CHLD_3;
+ } else if (flag == BluetoothHeadsetClient.CALL_ACCEPT_NONE) {
+ action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2;
} else {
action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2;
}
@@ -475,11 +482,8 @@
}
if (flag == BluetoothHeadsetClient.CALL_ACCEPT_HOLD) {
- // HFP is disabled when a call is put on hold to ensure correct audio routing for
- // cellular calls accepted while an HFP call is in progress. Reenable HFP when the HFP
- // call is put off hold.
- Log.d(TAG,"hfp_enable=true");
- mAudioManager.setParameters("hfp_enable=true");
+ // When unholding a call over Bluetooth make sure to route audio.
+ routeHfpAudio(true);
}
if (NativeInterface.handleCallActionNative(getByteAddress(mCurrentDevice), action, 0)) {
@@ -555,11 +559,6 @@
action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2;
}
- // Set HFP enable to false in case the call is being held to accept a cellular call. This
- // allows the cellular call's audio to be correctly routed.
- Log.d(TAG,"hfp_enable=false");
- mAudioManager.setParameters("hfp_enable=false");
-
if (NativeInterface.handleCallActionNative(getByteAddress(mCurrentDevice), action, 0)) {
addQueuedAction(HOLD_CALL, action);
} else {
@@ -669,7 +668,11 @@
mService = context;
mAdapter = BluetoothAdapter.getDefaultAdapter();
- mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ if (sAudioManager == null) {
+ sAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ // Initialize hfp_enable into a known state.
+ routeHfpAudio(false);
+ }
mAudioState = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED;
mAudioWbs = false;
@@ -680,8 +683,8 @@
mIndicatorNetworkSignal = 0;
mIndicatorBatteryLevel = 0;
- mMaxAmVcVol = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL);
- mMinAmVcVol = mAudioManager.getStreamMinVolume(AudioManager.STREAM_VOICE_CALL);
+ mMaxAmVcVol = sAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL);
+ mMinAmVcVol = sAudioManager.getStreamMinVolume(AudioManager.STREAM_VOICE_CALL);
mOperatorName = null;
mSubscriberInfo = null;
@@ -714,10 +717,22 @@
return hfcsm;
}
+ static synchronized void routeHfpAudio(boolean enable) {
+ if (DBG) {
+ Log.d(TAG, "hfp_enable=" + enable);
+ }
+ if (enable && !sAudioIsRouted) {
+ sAudioManager.setParameters("hfp_enable=true");
+ } else if (!enable) {
+ sAudioManager.setParameters("hfp_enable=false");
+ }
+ sAudioIsRouted = enable;
+ }
+
public void doQuit() {
Log.d(TAG, "doQuit");
- if (mAudioManager != null) {
- mAudioManager.setParameters("hfp_enable=false");
+ if (sAudioManager != null) {
+ routeHfpAudio(false);
}
quitNow();
}
@@ -988,13 +1003,13 @@
}
transitionTo(mConnected);
- int amVol = mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
+ int amVol = sAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
sendMessage(
obtainMessage(HeadsetClientStateMachine.SET_SPEAKER_VOLUME, amVol, 0));
// Mic is either in ON state (full volume) or OFF state. There is no way in
// Android to change the MIC volume.
sendMessage(obtainMessage(HeadsetClientStateMachine.SET_MIC_VOLUME,
- mAudioManager.isMicrophoneMute() ? 0 : 15, 0));
+ sAudioManager.isMicrophoneMute() ? 0 : 15, 0));
// query subscriber info
sendMessage(HeadsetClientStateMachine.SUBSCRIBER_INFO);
@@ -1036,12 +1051,15 @@
}
class Connected extends State {
+ int mCommandedSpeakerVolume = -1;
+
@Override
public void enter() {
if (DBG) {
Log.d(TAG, "Enter Connected: " + getCurrentMessage().what);
}
mAudioWbs = false;
+ mCommandedSpeakerVolume = -1;
}
@Override
@@ -1065,7 +1083,6 @@
}
NativeInterface.connectNative(getByteAddress(device));
- // deferMessage(message);
break;
case DISCONNECT:
BluetoothDevice dev = (BluetoothDevice) message.obj;
@@ -1083,11 +1100,8 @@
break;
case CONNECT_AUDIO:
- if (!mService.isScoAvailable()
- || !NativeInterface.connectAudioNative(
- getByteAddress(mCurrentDevice))) {
- Log.e(TAG, "ERROR: Couldn't connect Audio for device " + mCurrentDevice
- + " isScoAvailable " + mService.isScoAvailable());
+ if (!NativeInterface.connectAudioNative(getByteAddress(mCurrentDevice))) {
+ Log.e(TAG, "ERROR: Couldn't connect Audio for device " + mCurrentDevice);
broadcastAudioState(mCurrentDevice,
BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED,
BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED);
@@ -1109,11 +1123,15 @@
// This message should always contain the volume in AudioManager max normalized.
int amVol = message.arg1;
int hfVol = amToHfVol(amVol);
- Log.d(TAG,"HF volume is set to " + hfVol);
- mAudioManager.setParameters("hfp_volume=" + hfVol);
- // We do not set the volume in native because multiple devices might be
- // connected and it does not make sense to synchronize them. Car becomes the
- // master in such case.
+ if (amVol != mCommandedSpeakerVolume) {
+ Log.d(TAG, "Volume" + amVol + ":" + mCommandedSpeakerVolume);
+ // Volume was changed by a 3rd party
+ mCommandedSpeakerVolume = -1;
+ if (NativeInterface.setVolumeNative(getByteAddress(mCurrentDevice),
+ HeadsetClientHalConstants.VOLUME_TYPE_SPK, hfVol)) {
+ addQueuedAction(SET_SPEAKER_VOLUME);
+ }
+ }
break;
case DIAL_NUMBER:
// Add the call as an outgoing call.
@@ -1294,15 +1312,13 @@
break;
case StackEvent.EVENT_TYPE_VOLUME_CHANGED:
if (event.valueInt == HeadsetClientHalConstants.VOLUME_TYPE_SPK) {
- Log.d(TAG, "AM volume set to " +
- hfToAmVol(event.valueInt2));
- mAudioManager.setStreamVolume(
- AudioManager.STREAM_VOICE_CALL,
- hfToAmVol(event.valueInt2),
- AudioManager.FLAG_SHOW_UI);
- } else if (event.valueInt ==
- HeadsetClientHalConstants.VOLUME_TYPE_MIC) {
- mAudioManager.setMicrophoneMute(event.valueInt2 == 0);
+ mCommandedSpeakerVolume = hfToAmVol(event.valueInt2);
+ Log.d(TAG, "AM volume set to " + mCommandedSpeakerVolume);
+ sAudioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,
+ +mCommandedSpeakerVolume, AudioManager.FLAG_SHOW_UI);
+ } else if (event.valueInt
+ == HeadsetClientHalConstants.VOLUME_TYPE_MIC) {
+ sAudioManager.setMicrophoneMute(event.valueInt2 == 0);
}
break;
case StackEvent.EVENT_TYPE_CMD_RESULT:
@@ -1398,12 +1414,21 @@
// for routing and volume purposes.
// NOTE: All calls here are routed via the setParameters which changes the
// routing at the Audio HAL level.
+
+ if (mService.isScoRouted()) {
+ StackEvent event =
+ new StackEvent(StackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED);
+ event.valueInt = state;
+ event.device = device;
+ sendMessageDelayed(StackEvent.STACK_EVENT, event, ROUTING_DELAY_MS);
+ break;
+ }
+
mAudioState = BluetoothHeadsetClient.STATE_AUDIO_CONNECTED;
// We need to set the volume after switching into HFP mode as some Audio HALs
// reset the volume to a known-default on mode switch.
- final int amVol =
- mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
+ final int amVol = sAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
final int hfVol = amToHfVol(amVol);
if (DBG) {
@@ -1413,19 +1438,19 @@
if (DBG) {
Log.d(TAG,"Setting sampling rate as 16000");
}
- mAudioManager.setParameters("hfp_set_sampling_rate=16000");
+ sAudioManager.setParameters("hfp_set_sampling_rate=16000");
}
else {
if (DBG) {
Log.d(TAG,"Setting sampling rate as 8000");
}
- mAudioManager.setParameters("hfp_set_sampling_rate=8000");
+ sAudioManager.setParameters("hfp_set_sampling_rate=8000");
}
if (DBG) {
Log.d(TAG, "hf_volume " + hfVol);
}
- mAudioManager.setParameters("hfp_enable=true");
- mAudioManager.setParameters("hfp_volume=" + hfVol);
+ routeHfpAudio(true);
+ sAudioManager.setParameters("hfp_volume=" + hfVol);
transitionTo(mAudioOn);
break;
@@ -1495,12 +1520,14 @@
* Machines state changing
*/
if (NativeInterface.disconnectAudioNative(getByteAddress(mCurrentDevice))) {
- if (DBG) {
- Log.d(TAG,"hfp_enable=false");
- }
- mAudioManager.setParameters("hfp_enable=false");
+ routeHfpAudio(false);
}
break;
+
+ case HOLD_CALL:
+ holdCall();
+ break;
+
case StackEvent.STACK_EVENT:
StackEvent event = (StackEvent) message.obj;
if (DBG) {
@@ -1561,15 +1588,13 @@
switch (state) {
case HeadsetClientHalConstants.AUDIO_STATE_DISCONNECTED:
+ removeMessages(DISCONNECT_AUDIO);
mAudioState = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED;
// Audio focus may still be held by the entity controlling the actual call
// (such as Telecom) and hence this will still keep the call around, there
// is not much we can do here since dropping the call without user consent
// even if the audio connection snapped may not be a good idea.
- if (DBG) {
- Log.d(TAG, "hfp_enable=false");
- }
- mAudioManager.setParameters("hfp_enable=false");
+ routeHfpAudio(false);
broadcastAudioState(device, BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED,
BluetoothHeadsetClient.STATE_AUDIO_CONNECTED);
transitionTo(mConnected);
diff --git a/src/com/android/bluetooth/hfpclient/NativeInterface.java b/src/com/android/bluetooth/hfpclient/NativeInterface.java
index d22bd64..a9b3115 100644
--- a/src/com/android/bluetooth/hfpclient/NativeInterface.java
+++ b/src/com/android/bluetooth/hfpclient/NativeInterface.java
@@ -311,9 +311,11 @@
Log.d(TAG, "onVolumeChange: address " + address + " event " + event);
}
HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
- // Ignore volume changes from the Phone. This is to avoid the scenario where we may have two
- // phones connected each tries to set different volumes.
- Log.w(TAG, "onVolumeChange: Ignoring message: " + event);
+ if (service != null) {
+ service.messageFromNative(event);
+ } else {
+ Log.w(TAG, "onVolumeChange: Ignoring message because service not available: " + event);
+ }
}
private void onCmdResult(int type, int cme, byte[] address) {
diff --git a/src/com/android/bluetooth/hfpclient/connserv/HfpClientConference.java b/src/com/android/bluetooth/hfpclient/connserv/HfpClientConference.java
index bd143b1..954b8b8 100644
--- a/src/com/android/bluetooth/hfpclient/connserv/HfpClientConference.java
+++ b/src/com/android/bluetooth/hfpclient/connserv/HfpClientConference.java
@@ -73,11 +73,6 @@
@Override
public void onUnhold() {
- if (getPrimaryConnection().getConnectionService()
- .getAllConnections().size() > 1) {
- Log.w(TAG, "Ignoring unhold; call hold on the foreground call");
- return;
- }
Log.d(TAG, "onUnhold");
mHeadsetProfile.acceptCall(mDevice, BluetoothHeadsetClient.CALL_ACCEPT_HOLD);
}
diff --git a/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnection.java b/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnection.java
index 749bb75..0aca701 100644
--- a/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnection.java
+++ b/src/com/android/bluetooth/hfpclient/connserv/HfpClientConnection.java
@@ -38,6 +38,7 @@
private BluetoothHeadsetClient mHeadsetProfile;
private BluetoothHeadsetClientCall mCurrentCall;
+ private int mPreviousCallState = -1;
private boolean mClosed;
private boolean mClosing = false;
private boolean mLocalDisconnect;
@@ -81,6 +82,7 @@
return;
}
+ mHeadsetProfile.connectAudio(device);
setInitializing();
setDialing();
finishInitializing();
@@ -161,12 +163,19 @@
setRinging();
break;
case BluetoothHeadsetClientCall.CALL_STATE_TERMINATED:
- // TODO Use more specific causes
- close(mLocalDisconnect ? DisconnectCause.LOCAL : DisconnectCause.REMOTE);
+ if (mPreviousCallState == BluetoothHeadsetClientCall.CALL_STATE_INCOMING
+ || mPreviousCallState == BluetoothHeadsetClientCall.CALL_STATE_WAITING) {
+ close(DisconnectCause.MISSED);
+ } else if (mLocalDisconnect) {
+ close(DisconnectCause.LOCAL);
+ } else {
+ close(DisconnectCause.REMOTE);
+ }
break;
default:
Log.wtf(TAG, "Unexpected phone state " + state);
}
+ mPreviousCallState = state;
}
public synchronized void close(int cause) {
@@ -256,6 +265,7 @@
if (!mClosed) {
mHeadsetProfile.acceptCall(mDevice, BluetoothHeadsetClient.CALL_ACCEPT_NONE);
}
+ mHeadsetProfile.connectAudio(mDevice);
}
@Override
diff --git a/src/com/android/bluetooth/hfpclient/connserv/HfpClientDeviceBlock.java b/src/com/android/bluetooth/hfpclient/connserv/HfpClientDeviceBlock.java
index ee7f16a..f891b90 100644
--- a/src/com/android/bluetooth/hfpclient/connserv/HfpClientDeviceBlock.java
+++ b/src/com/android/bluetooth/hfpclient/connserv/HfpClientDeviceBlock.java
@@ -192,15 +192,15 @@
// (represented as unknown call in telecom since). Since BluetoothHeadsetClientCall is a
// parcelable we simply pack the entire object in there.
Bundle b = new Bundle();
- if (call.getState() == BluetoothHeadsetClientCall.CALL_STATE_DIALING ||
- call.getState() == BluetoothHeadsetClientCall.CALL_STATE_ALERTING ||
- call.getState() == BluetoothHeadsetClientCall.CALL_STATE_ACTIVE ||
- call.getState() == BluetoothHeadsetClientCall.CALL_STATE_WAITING) {
+ if (call.getState() == BluetoothHeadsetClientCall.CALL_STATE_DIALING
+ || call.getState() == BluetoothHeadsetClientCall.CALL_STATE_ALERTING
+ || call.getState() == BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) {
// This is an outgoing call. Even if it is an active call we do not have a way of
// putting that parcelable in a seaprate field.
b.putParcelable(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, call);
mTelecomManager.addNewUnknownCall(mPhoneAccount.getAccountHandle(), b);
- } else if (call.getState() == BluetoothHeadsetClientCall.CALL_STATE_INCOMING) {
+ } else if (call.getState() == BluetoothHeadsetClientCall.CALL_STATE_INCOMING
+ || call.getState() == BluetoothHeadsetClientCall.CALL_STATE_WAITING) {
// This is an incoming call.
b.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, call);
mTelecomManager.addNewIncomingCall(mPhoneAccount.getAccountHandle(), b);
diff --git a/src/com/android/bluetooth/mapclient/MnsService.java b/src/com/android/bluetooth/mapclient/MnsService.java
index 7b3419e..1078cf1 100644
--- a/src/com/android/bluetooth/mapclient/MnsService.java
+++ b/src/com/android/bluetooth/mapclient/MnsService.java
@@ -50,26 +50,49 @@
static private MapClientService mContext;
private volatile boolean mShutdown = false; // Used to interrupt socket accept thread
+ private int mSdpHandle = -1;
MnsService(MapClientService context) {
if (VDBG) Log.v(TAG, "MnsService()");
mContext = context;
mAcceptThread = new SocketAcceptor();
mServerSockets = ObexServerSockets.create(mAcceptThread);
- SdpManager.getDefaultManager().createMapMnsRecord(
- "MAP Message Notification Service", mServerSockets.getRfcommChannel(), -1,
- MNS_VERSION, MNS_FEATURE_BITS);
+ SdpManager sdpManager = SdpManager.getDefaultManager();
+ if (sdpManager == null) {
+ Log.e(TAG, "SdpManager is null");
+ return;
+ }
+ mSdpHandle = sdpManager.createMapMnsRecord("MAP Message Notification Service",
+ mServerSockets.getRfcommChannel(), -1, MNS_VERSION, MNS_FEATURE_BITS);
}
void stop() {
if (VDBG) Log.v(TAG, "stop()");
mShutdown = true;
+ cleanUpSdpRecord();
if (mServerSockets != null) {
mServerSockets.shutdown(false);
mServerSockets = null;
}
}
+ private void cleanUpSdpRecord() {
+ if (mSdpHandle < 0) {
+ Log.e(TAG, "cleanUpSdpRecord, SDP record never created");
+ return;
+ }
+ int sdpHandle = mSdpHandle;
+ mSdpHandle = -1;
+ SdpManager sdpManager = SdpManager.getDefaultManager();
+ if (sdpManager == null) {
+ Log.e(TAG, "cleanUpSdpRecord failed, sdpManager is null, sdpHandle=" + sdpHandle);
+ return;
+ }
+ Log.i(TAG, "cleanUpSdpRecord, mSdpHandle=" + sdpHandle);
+ if (!sdpManager.removeSdpRecord(sdpHandle)) {
+ Log.e(TAG, "cleanUpSdpRecord, removeSdpRecord failed, sdpHandle=" + sdpHandle);
+ }
+ }
private class SocketAcceptor implements IObexConnectionHandler {
diff --git a/src/com/android/bluetooth/opp/BluetoothOppService.java b/src/com/android/bluetooth/opp/BluetoothOppService.java
index b68936a..7f94820 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppService.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppService.java
@@ -226,14 +226,6 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case STOP_LISTENER:
- if (mAdapter != null && mOppSdpHandle >= 0
- && SdpManager.getDefaultManager() != null) {
- if (D) Log.d(TAG, "Removing SDP record mOppSdpHandle :" + mOppSdpHandle);
- boolean status =
- SdpManager.getDefaultManager().removeSdpRecord(mOppSdpHandle);
- Log.d(TAG, "RemoveSDPrecord returns " + status);
- mOppSdpHandle = -1;
- }
stopListeners();
mListenStarted = false;
//Stop Active INBOUND Transfer
@@ -365,8 +357,10 @@
+ " mServerSocket:" + mServerSocket);
return;
}
- sdpManager.createOppOpsRecord("OBEX Object Push", mServerSocket.getRfcommChannel(),
- mServerSocket.getL2capPsm(), 0x0102, SUPPORTED_OPP_FORMAT);
+ mOppSdpHandle =
+ sdpManager.createOppOpsRecord("OBEX Object Push", mServerSocket.getRfcommChannel(),
+ mServerSocket.getL2capPsm(), 0x0102, SUPPORTED_OPP_FORMAT);
+ if (D) Log.d(TAG, "mOppSdpHandle :" + mOppSdpHandle);
}
@Override
@@ -1063,6 +1057,12 @@
}
private void stopListeners() {
+ if (mAdapter != null && mOppSdpHandle >= 0 && SdpManager.getDefaultManager() != null) {
+ if (D) Log.d(TAG, "Removing SDP record mOppSdpHandle :" + mOppSdpHandle);
+ boolean status = SdpManager.getDefaultManager().removeSdpRecord(mOppSdpHandle);
+ Log.d(TAG, "RemoveSDPrecord returns " + status);
+ mOppSdpHandle = -1;
+ }
if (mServerSocket != null) {
mServerSocket.shutdown(false);
mServerSocket = null;
diff --git a/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java b/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java
index 21fad6b..fd47318 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java
@@ -39,6 +39,7 @@
import android.bluetooth.BluetoothAdapter;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
@@ -118,11 +119,12 @@
final String sortOrder = BluetoothShare.TIMESTAMP + " DESC";
- mTransferCursor = managedQuery(BluetoothShare.CONTENT_URI, new String[] {
- "_id", BluetoothShare.FILENAME_HINT, BluetoothShare.STATUS,
- BluetoothShare.TOTAL_BYTES, BluetoothShare._DATA, BluetoothShare.TIMESTAMP,
- BluetoothShare.VISIBILITY, BluetoothShare.DESTINATION, BluetoothShare.DIRECTION
- }, selection, sortOrder);
+ mTransferCursor = getContentResolver().query(BluetoothShare.CONTENT_URI,
+ new String[] {"_id", BluetoothShare.FILENAME_HINT, BluetoothShare.STATUS,
+ BluetoothShare.TOTAL_BYTES, BluetoothShare._DATA, BluetoothShare.TIMESTAMP,
+ BluetoothShare.VISIBILITY, BluetoothShare.DESTINATION,
+ BluetoothShare.DIRECTION},
+ selection, null, sortOrder);
// only attach everything to the listbox if we can access
// the transfer database. Otherwise, just show it empty
@@ -193,6 +195,14 @@
}
@Override
+ protected void onDestroy() {
+ if (mTransferCursor != null) {
+ mTransferCursor.close();
+ }
+ super.onDestroy();
+ }
+
+ @Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
if (mTransferCursor != null) {
mContextMenu = true;
diff --git a/src/com/android/bluetooth/pan/PanService.java b/src/com/android/bluetooth/pan/PanService.java
index 391ea3a..a978693 100755
--- a/src/com/android/bluetooth/pan/PanService.java
+++ b/src/com/android/bluetooth/pan/PanService.java
@@ -472,6 +472,7 @@
// will fail until the caller explicitly calls BluetoothPan#disconnect.
if (prevState == BluetoothProfile.STATE_DISCONNECTED && state == BluetoothProfile.STATE_DISCONNECTING) {
Log.d(TAG, "Ignoring state change from " + prevState + " to " + state);
+ mPanDevices.remove(device);
return;
}
diff --git a/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java b/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java
index d91d9a2..325a386 100644
--- a/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java
+++ b/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java
@@ -217,6 +217,7 @@
final int callLogType = mCursor.getInt(CALL_TYPE_COLUMN_INDEX);
final String callLogTypeStr;
switch (callLogType) {
+ case Calls.REJECTED_TYPE:
case Calls.INCOMING_TYPE: {
callLogTypeStr = VCARD_PROPERTY_CALLTYPE_INCOMING;
break;
diff --git a/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java b/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java
index d112bfd..01f8be9 100644
--- a/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java
+++ b/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java
@@ -763,7 +763,7 @@
for (int pos = appParamValue.listStartOffset;
pos < listSize && itemsFound < requestSize; pos++) {
currentValue = nameList.get(pos);
- if (D) Log.d(TAG, "currentValue=" + currentValue);
+ if (V) Log.d(TAG, "currentValue=" + currentValue);
if (currentValue.equals(compareValue)) {
itemsFound++;
if (currentValue.contains(","))
diff --git a/src/com/android/bluetooth/pbap/BluetoothPbapService.java b/src/com/android/bluetooth/pbap/BluetoothPbapService.java
index 7743d9b..7e1164e 100644
--- a/src/com/android/bluetooth/pbap/BluetoothPbapService.java
+++ b/src/com/android/bluetooth/pbap/BluetoothPbapService.java
@@ -437,17 +437,43 @@
mWakeLock = null;
}
+ // Step 1: clean up active server session
if (mServerSession != null) {
mServerSession.close();
mServerSession = null;
}
-
+ // Step 2: clean up existing connection socket
closeConnectionSocket();
+ // Step 3: clean up SDP record
+ cleanUpSdpRecord();
+ // Step 4: clean up existing server socket(s)
closeServerSocket();
+ if (mServerSockets != null) {
+ mServerSockets.shutdown(false);
+ mServerSockets = null;
+ }
if (mSessionStatusHandler != null) mSessionStatusHandler.removeCallbacksAndMessages(null);
if (VERBOSE) Log.v(TAG, "Pbap Service closeService out");
}
+ private void cleanUpSdpRecord() {
+ if (mSdpHandle < 0) {
+ if (VERBOSE) Log.v(TAG, "cleanUpSdpRecord, SDP record never created");
+ return;
+ }
+ int sdpHandle = mSdpHandle;
+ mSdpHandle = -1;
+ SdpManager sdpManager = SdpManager.getDefaultManager();
+ if (sdpManager == null) {
+ Log.e(TAG, "cleanUpSdpRecord failed, sdpManager is null, sdpHandle=" + sdpHandle);
+ return;
+ }
+ Log.i(TAG, "cleanUpSdpRecord, mSdpHandle=" + sdpHandle);
+ if (!sdpManager.removeSdpRecord(sdpHandle)) {
+ Log.e(TAG, "cleanUpSdpRecord, removeSdpRecord failed, sdpHandle=" + sdpHandle);
+ }
+ }
+
private final void startObexServerSession() throws IOException {
if (VERBOSE) Log.v(TAG, "Pbap Service startObexServerSession");
@@ -935,6 +961,10 @@
}
}
+ /**
+ * Start server side socket listeners. Caller should make sure that adapter is in a ready state
+ * and SDP record is cleaned up. Otherwise, this method will fail.
+ */
synchronized private void startSocketListeners() {
if (DEBUG) Log.d(TAG, "startsocketListener");
if (mServerSession != null) {
@@ -952,17 +982,10 @@
Log.e(TAG, "Failed to start the listeners");
return;
}
- SdpManager sdpManager = SdpManager.getDefaultManager();
- if (sdpManager == null) {
- Log.e(TAG, "Failed to start the listeners sdp null ");
+ if (mSdpHandle >= 0) {
+ Log.e(TAG, "SDP handle was not cleaned up, mSdpHandle=" + mSdpHandle);
return;
}
- if (mAdapter != null && mSdpHandle >= 0) {
- Log.d(TAG, "Removing SDP record for PBAP with SDP handle:" + mSdpHandle);
- boolean status = sdpManager.removeSdpRecord(mSdpHandle);
- Log.d(TAG, "RemoveSDPrecord returns " + status);
- mSdpHandle = -1;
- }
mSdpHandle = SdpManager.getDefaultManager().createPbapPseRecord(
"OBEX Phonebook Access Server", mServerSockets.getRfcommChannel(),
mServerSockets.getL2capPsm(), SDP_PBAP_SERVER_VERSION,
@@ -1053,8 +1076,13 @@
*/
@Override
public synchronized void onAcceptFailed() {
+ // Clean up SDP record first
+ cleanUpSdpRecord();
// Force socket listener to restart
- mServerSockets = null;
+ if (mServerSockets != null) {
+ mServerSockets.shutdown(false);
+ mServerSockets = null;
+ }
if (!mInterrupted && mAdapter != null && mAdapter.isEnabled()) {
startSocketListeners();
}
diff --git a/src/com/android/bluetooth/sap/SapServer.java b/src/com/android/bluetooth/sap/SapServer.java
index a66fc46..8f8da2d 100644
--- a/src/com/android/bluetooth/sap/SapServer.java
+++ b/src/com/android/bluetooth/sap/SapServer.java
@@ -115,13 +115,15 @@
IntentFilter filter = new IntentFilter();
filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
filter.addAction(SAP_DISCONNECT_ACTION);
+ mIntentReceiver = new SapServerBroadcastReceiver();
mContext.registerReceiver(mIntentReceiver, filter);
}
/**
* This handles the response from RIL.
*/
- BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ private BroadcastReceiver mIntentReceiver;
+ private class SapServerBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
@@ -148,8 +150,7 @@
if(disconnectType == SapMessage.DISC_RFCOMM) {
// At timeout we need to close the RFCOMM socket to complete shutdown
shutdown();
- } else if( mState != SAP_STATE.DISCONNECTED
- && mState != SAP_STATE.DISCONNECTING ) {
+ } else if (mState != SAP_STATE.DISCONNECTED && mState != SAP_STATE.DISCONNECTING) {
// The user pressed disconnect - initiate disconnect sequence.
sendDisconnectInd(disconnectType);
}
@@ -157,7 +158,7 @@
Log.w(TAG, "RIL-BT received unexpected Intent: " + intent.getAction());
}
}
- };
+ }
/**
* Set RIL driver in test mode - only possible if SapMessage is build with TEST == true
diff --git a/tests/src/com/android/bluetooth/hfpclient/HeadsetClientServiceTest.java b/tests/src/com/android/bluetooth/hfpclient/HeadsetClientServiceTest.java
index 3a3edf9..70825ff 100644
--- a/tests/src/com/android/bluetooth/hfpclient/HeadsetClientServiceTest.java
+++ b/tests/src/com/android/bluetooth/hfpclient/HeadsetClientServiceTest.java
@@ -42,7 +42,7 @@
assertTrue(mService != null);
// At this point Adapter Service should have started
- AdapterService inst = AdapterService.getAdapterService();
+ AdapterService inst = mock(AdapterService.class);
assertTrue(inst != null);
// Try getting the Bluetooth adapter
diff --git a/tests/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java b/tests/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java
index a8b2c59..68adb29 100644
--- a/tests/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java
+++ b/tests/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java
@@ -18,6 +18,7 @@
import com.android.bluetooth.btservice.AdapterService;
import static org.mockito.Mockito.*;
+
import org.mockito.ArgumentCaptor;
public class HeadsetClientStateMachineTest extends AndroidTestCase {
@@ -25,7 +26,7 @@
@Override
protected void setUp() throws Exception {
- AdapterService inst = AdapterService.getAdapterService();
+ AdapterService inst = mock(AdapterService.class);
assertTrue(inst != null);
mAdapter = BluetoothAdapter.getDefaultAdapter();
}
diff --git a/tests/src/com/android/bluetooth/pbapclient/PbapParserTest.java b/tests/src/com/android/bluetooth/pbapclient/PbapParserTest.java
index 5007238..93b02b3 100644
--- a/tests/src/com/android/bluetooth/pbapclient/PbapParserTest.java
+++ b/tests/src/com/android/bluetooth/pbapclient/PbapParserTest.java
@@ -81,11 +81,11 @@
processor.setResults(pbapVCardList.getList());
// Verify that these entries aren't in the call log to start.
- assertFalse(verifyCallLog("555-0002", "1483232460000", "3"));
-
+ // EST is default Time Zone
+ assertFalse(verifyCallLog("555-0002", "1483250460000", "3"));
// Finish processing the data and verify entries were added to the call log.
processor.onPullComplete();
- assertTrue(verifyCallLog("555-0002", "1483232460000", "3"));
+ assertTrue(verifyCallLog("555-0002", "1483250460000", "3"));
}
// testUnknownCall should parse two calls with no phone number.
@@ -102,13 +102,14 @@
processor.setResults(pbapVCardList.getList());
// Verify that these entries aren't in the call log to start.
- assertFalse(verifyCallLog("", "1483232520000", "3"));
- assertFalse(verifyCallLog("", "1483232580000", "3"));
+ // EST is default Time Zone
+ assertFalse(verifyCallLog("", "1483250520000", "3"));
+ assertFalse(verifyCallLog("", "1483250580000", "3"));
// Finish processing the data and verify entries were added to the call log.
processor.onPullComplete();
- assertTrue(verifyCallLog("", "1483232520000", "3"));
- assertTrue(verifyCallLog("", "1483232580000", "3"));
+ assertTrue(verifyCallLog("", "1483250520000", "3"));
+ assertTrue(verifyCallLog("", "1483250580000", "3"));
}
// Find Entries in call log with type matching number and date.