diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:05:43 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:05:43 -0800 |
commit | f013e1afd1e68af5e3b868c26a653bbfb39538f8 (patch) | |
tree | 7ad6c8fd9c7b55f4b4017171dec1cb760bbd26bf /core/jni/android_server_BluetoothEventLoop.cpp | |
parent | e70cfafe580c6f2994c4827cd8a534aabf3eb05c (diff) | |
download | frameworks_base-f013e1afd1e68af5e3b868c26a653bbfb39538f8.zip frameworks_base-f013e1afd1e68af5e3b868c26a653bbfb39538f8.tar.gz frameworks_base-f013e1afd1e68af5e3b868c26a653bbfb39538f8.tar.bz2 |
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'core/jni/android_server_BluetoothEventLoop.cpp')
-rw-r--r-- | core/jni/android_server_BluetoothEventLoop.cpp | 161 |
1 files changed, 100 insertions, 61 deletions
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp index 395a45c..1aef138 100644 --- a/core/jni/android_server_BluetoothEventLoop.cpp +++ b/core/jni/android_server_BluetoothEventLoop.cpp @@ -39,6 +39,7 @@ namespace android { static jfieldID field_mNativeData; static jmethodID method_onModeChanged; +static jmethodID method_onNameChanged; static jmethodID method_onDiscoveryStarted; static jmethodID method_onDiscoveryCompleted; static jmethodID method_onRemoteDeviceFound; @@ -60,17 +61,10 @@ static jmethodID method_onGetRemoteServiceChannelResult; static jmethodID method_onPasskeyAgentRequest; static jmethodID method_onPasskeyAgentCancel; -struct native_data_t { - DBusConnection *conn; - /* These variables are set in waitForAndDispatchEventNative() and are - valid only within the scope of this function. At any other time, they - are NULL. */ - jobject me; - JNIEnv *env; -}; +typedef event_loop_native_data_t native_data_t; // Only valid during waitForAndDispatchEventNative() -static native_data_t *event_loop_nat; +native_data_t *event_loop_nat; static inline native_data_t * get_native_data(JNIEnv *env, jobject object) { return (native_data_t *)(env->GetIntField(object, @@ -83,6 +77,7 @@ static void classInitNative(JNIEnv* env, jclass clazz) { #ifdef HAVE_BLUETOOTH method_onModeChanged = env->GetMethodID(clazz, "onModeChanged", "(Ljava/lang/String;)V"); + method_onNameChanged = env->GetMethodID(clazz, "onNameChanged", "(Ljava/lang/String;)V"); method_onDiscoveryStarted = env->GetMethodID(clazz, "onDiscoveryStarted", "()V"); method_onDiscoveryCompleted = env->GetMethodID(clazz, "onDiscoveryCompleted", "()V"); method_onRemoteDeviceFound = env->GetMethodID(clazz, "onRemoteDeviceFound", "(Ljava/lang/String;IS)V"); @@ -142,8 +137,6 @@ static void cleanupNativeDataNative(JNIEnv* env, jobject object) { } #ifdef HAVE_BLUETOOTH -static jboolean add_adapter_event_match(JNIEnv *env, native_data_t *nat); -static void remove_adapter_event_match(JNIEnv *env, native_data_t *nat); static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg, void *data); static DBusHandlerResult passkey_agent_event_filter(DBusConnection *conn, @@ -160,15 +153,46 @@ static jboolean setUpEventLoopNative(JNIEnv *env, jobject object) { LOGV(__FUNCTION__); dbus_threads_init_default(); native_data_t *nat = get_native_data(env, object); + DBusError err; + dbus_error_init(&err); + if (nat != NULL && nat->conn != NULL) { + // Add a filter for all incoming messages if (!dbus_connection_add_filter(nat->conn, event_filter, nat, NULL)){ return JNI_FALSE; } - if (add_adapter_event_match(env, nat) != JNI_TRUE) { + // Set which messages will be processed by this dbus connection + dbus_bus_add_match(nat->conn, + "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Adapter'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + return JNI_FALSE; + } + dbus_bus_add_match(nat->conn, + "type='signal',interface='org.bluez.audio.Manager'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + return JNI_FALSE; + } + dbus_bus_add_match(nat->conn, + "type='signal',interface='org.bluez.audio.Device'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + return JNI_FALSE; + } + dbus_bus_add_match(nat->conn, + "type='signal',interface='org.bluez.audio.Sink'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); return JNI_FALSE; } + // Add an object handler for passkey agent method calls const char *path = "/android/bluetooth/PasskeyAgent"; if (!dbus_connection_register_object_path(nat->conn, path, &passkey_agent_vtable, NULL)) { @@ -177,9 +201,6 @@ static jboolean setUpEventLoopNative(JNIEnv *env, jobject object) { return JNI_FALSE; } - DBusError err; - dbus_error_init(&err); - // RegisterDefaultPasskeyAgent() will fail until hcid is up, so keep // trying for 10 seconds. int attempt; @@ -219,6 +240,9 @@ static void tearDownEventLoopNative(JNIEnv *env, jobject object) { native_data_t *nat = get_native_data(env, object); if (nat != NULL && nat->conn != NULL) { + DBusError err; + dbus_error_init(&err); + const char *path = "/android/bluetooth/PasskeyAgent"; DBusMessage *reply = dbus_func_args(env, nat->conn, BLUEZ_DBUS_BASE_PATH, @@ -227,50 +251,40 @@ static void tearDownEventLoopNative(JNIEnv *env, jobject object) { DBUS_TYPE_INVALID); if (reply) dbus_message_unref(reply); - DBusError err; - dbus_error_init(&err); - (void)dbus_connection_remove_filter(nat->conn, - event_filter, - nat); - dbus_connection_unregister_object_path(nat->conn, path); - remove_adapter_event_match(env, nat); + dbus_bus_remove_match(nat->conn, + "type='signal',interface='org.bluez.audio.Sink'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + } + dbus_bus_remove_match(nat->conn, + "type='signal',interface='org.bluez.audio.Device'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + } + dbus_bus_remove_match(nat->conn, + "type='signal',interface='org.bluez.audio.Manager'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + } + dbus_bus_remove_match(nat->conn, + "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Adapter'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + } + + dbus_connection_remove_filter(nat->conn, event_filter, nat); } #endif } #ifdef HAVE_BLUETOOTH -static const char *const adapter_event_match = - "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Adapter'"; - -static jboolean add_adapter_event_match(JNIEnv *env, native_data_t *nat) { - if (nat == NULL || nat->conn == NULL) { - LOGE("%s: Not connected to d-bus!", __FUNCTION__); - return JNI_FALSE; - } - DBusError err; - dbus_error_init(&err); - dbus_bus_add_match(nat->conn, adapter_event_match, &err); - if (dbus_error_is_set(&err)) { - LOG_AND_FREE_DBUS_ERROR(&err); - return JNI_FALSE; - } - return JNI_TRUE; -} - -static void remove_adapter_event_match(JNIEnv *env, native_data_t *nat) { - if (nat->conn == NULL) { - LOGE("%s: Not connected to d-bus!", __FUNCTION__); - return; - } - DBusError err; - dbus_error_init(&err); - dbus_bus_remove_match(nat->conn, adapter_event_match, &err); - if (dbus_error_is_set(&err)) { - LOG_AND_FREE_DBUS_ERROR(&err); - } -} +extern DBusHandlerResult a2dp_event_filter(DBusMessage *msg, JNIEnv *env); // Called by dbus during WaitForAndDispatchEventNative() static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg, @@ -288,8 +302,9 @@ static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } - LOGV("%s: Received signal %s:%s", __FUNCTION__, - dbus_message_get_interface(msg), dbus_message_get_member(msg)); + LOGV("%s: Received signal %s:%s from %s", __FUNCTION__, + dbus_message_get_interface(msg), dbus_message_get_member(msg), + dbus_message_get_path(msg)); if (dbus_message_is_signal(msg, "org.bluez.Adapter", @@ -471,11 +486,35 @@ static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg, env->NewStringUTF(c_address)); } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); return DBUS_HANDLER_RESULT_HANDLED; - } else { - LOGV("... ignored"); + } else if (dbus_message_is_signal(msg, + "org.bluez.Adapter", + "ModeChanged")) { + char *c_mode; + if (dbus_message_get_args(msg, &err, + DBUS_TYPE_STRING, &c_mode, + DBUS_TYPE_INVALID)) { + LOGV("... mode = %s", c_mode); + env->CallVoidMethod(nat->me, + method_onModeChanged, + env->NewStringUTF(c_mode)); + } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); + return DBUS_HANDLER_RESULT_HANDLED; + } else if (dbus_message_is_signal(msg, + "org.bluez.Adapter", + "NameChanged")) { + char *c_name; + if (dbus_message_get_args(msg, &err, + DBUS_TYPE_STRING, &c_name, + DBUS_TYPE_INVALID)) { + LOGV("... name = %s", c_name); + env->CallVoidMethod(nat->me, + method_onNameChanged, + env->NewStringUTF(c_name)); + } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); + return DBUS_HANDLER_RESULT_HANDLED; } - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + return a2dp_event_filter(msg, env); } // Called by dbus during WaitForAndDispatchEventNative() @@ -557,9 +596,9 @@ static jboolean waitForAndDispatchEventNative(JNIEnv *env, jobject object, nat->me = object; nat->env = env; event_loop_nat = nat; - ret = dbus_connection_read_write_dispatch(nat->conn, - timeout_ms) == TRUE ? - JNI_TRUE : JNI_FALSE; + ret = dbus_connection_read_write_dispatch_greedy(nat->conn, + timeout_ms) == TRUE ? + JNI_TRUE : JNI_FALSE; event_loop_nat = NULL; nat->me = NULL; nat->env = NULL; @@ -604,7 +643,7 @@ void onGetRemoteServiceChannelResult(DBusMessage *msg, void *user) { JNIEnv *env = event_loop_nat->env; jint channel = -2; - LOGV("... address = %s", context->address); + LOGV("... address = %s", address); if (dbus_set_error_from_message(&err, msg) || !dbus_message_get_args(msg, &err, |