summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/server/BluetoothA2dpService.java26
-rw-r--r--core/jni/android_server_BluetoothA2dpService.cpp38
2 files changed, 58 insertions, 6 deletions
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index f2e132b..03dcf00 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -305,7 +305,11 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
return false;
// State is DISCONNECTED
+ handleSinkStateChange(device, state, BluetoothA2dp.STATE_CONNECTING);
+
if (!connectSinkNative(path)) {
+ // Restore previous state
+ handleSinkStateChange(device, mAudioDevices.get(device), state);
return false;
}
return true;
@@ -321,7 +325,8 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
return false;
}
- switch (getSinkState(device)) {
+ int state = getSinkState(device);
+ switch (state) {
case BluetoothA2dp.STATE_DISCONNECTED:
return false;
case BluetoothA2dp.STATE_DISCONNECTING:
@@ -329,11 +334,13 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
}
// State is CONNECTING or CONNECTED or PLAYING
+ handleSinkStateChange(device, state, BluetoothA2dp.STATE_DISCONNECTING);
if (!disconnectSinkNative(path)) {
+ // Restore previous state
+ handleSinkStateChange(device, mAudioDevices.get(device), state);
return false;
- } else {
- return true;
}
+ return true;
}
public synchronized boolean suspendSink(BluetoothDevice device) {
@@ -512,6 +519,19 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
return result;
}
+ private void onConnectSinkResult(String deviceObjectPath, boolean result) {
+ // If the call was a success, ignore we will update the state
+ // when we a Sink Property Change
+ if (!result) {
+ if (deviceObjectPath != null) {
+ String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
+ BluetoothDevice device = mAdapter.getRemoteDevice(address);
+ int state = getSinkState(device);
+ handleSinkStateChange(device, state, BluetoothA2dp.STATE_DISCONNECTED);
+ }
+ }
+ }
+
@Override
protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mAudioDevices.isEmpty()) return;
diff --git a/core/jni/android_server_BluetoothA2dpService.cpp b/core/jni/android_server_BluetoothA2dpService.cpp
index 7a3bbbb..4eab4b3 100644
--- a/core/jni/android_server_BluetoothA2dpService.cpp
+++ b/core/jni/android_server_BluetoothA2dpService.cpp
@@ -38,6 +38,7 @@ namespace android {
#ifdef HAVE_BLUETOOTH
static jmethodID method_onSinkPropertyChanged;
+static jmethodID method_onConnectSinkResult;
typedef struct {
JavaVM *vm;
@@ -47,6 +48,7 @@ typedef struct {
} native_data_t;
static native_data_t *nat = NULL; // global native data
+static void onConnectSinkResult(DBusMessage *msg, void *user, void *n);
static Properties sink_properties[] = {
{"State", DBUS_TYPE_STRING},
@@ -133,9 +135,12 @@ static jboolean connectSinkNative(JNIEnv *env, jobject object, jstring path) {
LOGV(__FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
+ int len = env->GetStringLength(path) + 1;
+ char *context_path = (char *)calloc(len, sizeof(char));
+ strlcpy(context_path, c_path, len); // for callback
- bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
- c_path, "org.bluez.AudioSink", "Connect",
+ bool ret = dbus_func_args_async(env, nat->conn, -1, onConnectSinkResult, context_path,
+ nat, c_path, "org.bluez.AudioSink", "Connect",
DBUS_TYPE_INVALID);
env->ReleaseStringUTFChars(path, c_path);
@@ -237,6 +242,31 @@ DBusHandlerResult a2dp_event_filter(DBusMessage *msg, JNIEnv *env) {
return result;
}
+
+void onConnectSinkResult(DBusMessage *msg, void *user, void *n) {
+ LOGV(__FUNCTION__);
+
+ native_data_t *nat = (native_data_t *)n;
+ const char *path = (const char *)user;
+ DBusError err;
+ dbus_error_init(&err);
+ JNIEnv *env;
+ nat->vm->GetEnv((void**)&env, nat->envVer);
+
+
+ bool result = JNI_TRUE;
+ if (dbus_set_error_from_message(&err, msg)) {
+ LOG_AND_FREE_DBUS_ERROR(&err);
+ result = JNI_FALSE;
+ }
+ LOGV("... Device Path = %s, result = %d", path, result);
+ env->CallVoidMethod(nat->me,
+ method_onConnectSinkResult,
+ env->NewStringUTF(path),
+ result);
+ free(user);
+}
+
#endif
@@ -244,7 +274,7 @@ static JNINativeMethod sMethods[] = {
{"initNative", "()Z", (void *)initNative},
{"cleanupNative", "()V", (void *)cleanupNative},
- /* Bluez audio 4.40 API */
+ /* Bluez audio 4.47 API */
{"connectSinkNative", "(Ljava/lang/String;)Z", (void *)connectSinkNative},
{"disconnectSinkNative", "(Ljava/lang/String;)Z", (void *)disconnectSinkNative},
{"suspendSinkNative", "(Ljava/lang/String;)Z", (void*)suspendSinkNative},
@@ -263,6 +293,8 @@ int register_android_server_BluetoothA2dpService(JNIEnv *env) {
#ifdef HAVE_BLUETOOTH
method_onSinkPropertyChanged = env->GetMethodID(clazz, "onSinkPropertyChanged",
"(Ljava/lang/String;[Ljava/lang/String;)V");
+ method_onConnectSinkResult = env->GetMethodID(clazz, "onConnectSinkResult",
+ "(Ljava/lang/String;Z)V");
#endif
return AndroidRuntime::registerNativeMethods(env,