diff options
author | Bernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org> | 2012-10-15 01:07:03 +0200 |
---|---|---|
committer | Bernhard Rosenkränzer <Bernhard.Rosenkranzer@linaro.org> | 2013-12-12 03:42:01 +0100 |
commit | 5546ab4a88a00b6da15821d037d993818a496e83 (patch) | |
tree | 79a1ba1c6793ef5e3c5995fa8a44e52fb85c29fb | |
parent | 7c6a81658938d4723abc2c6ef8bd8da0ff706c4c (diff) | |
download | base-5546ab4a88a00b6da15821d037d993818a496e83.tar.gz |
base: Fix build after Parcel ABI fix in Binder
Adapt code to the fact that writeString16's first parameter
is now an uint16_t* to match the old ABI
Change-Id: I138af645c877f343f0490152b9702698b7d36582
Signed-off-by: Bernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org>
-rw-r--r-- | core/jni/android_os_Parcel.cpp | 2 | ||||
-rw-r--r-- | core/jni/android_server_BluetoothEventLoop.cpp | 1585 |
2 files changed, 1 insertions, 1586 deletions
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp index d7eaa23943c4..a90987990646 100644 --- a/core/jni/android_os_Parcel.cpp +++ b/core/jni/android_os_Parcel.cpp @@ -236,7 +236,7 @@ static void android_os_Parcel_writeString(JNIEnv* env, jclass clazz, jint native if (val) { const jchar* str = env->GetStringCritical(val, 0); if (str) { - err = parcel->writeString16((char16_t*)str, env->GetStringLength(val)); + err = parcel->writeString16((uint16_t*)str, env->GetStringLength(val)); env->ReleaseStringCritical(val, str); } } else { diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp deleted file mode 100644 index e498f0a44ac5..000000000000 --- a/core/jni/android_server_BluetoothEventLoop.cpp +++ /dev/null @@ -1,1585 +0,0 @@ -/* -** Copyright 2008, 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. -*/ - -#define LOG_TAG "BluetoothEventLoop.cpp" - -#include "android_bluetooth_common.h" -#include "android_runtime/AndroidRuntime.h" -#include "cutils/sockets.h" -#include "JNIHelp.h" -#include "jni.h" -#include "utils/Log.h" -#include "utils/misc.h" - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> - -#ifdef HAVE_BLUETOOTH -#include <dbus/dbus.h> -#endif - -namespace android { - -#define CREATE_DEVICE_ALREADY_EXISTS 1 -#define CREATE_DEVICE_SUCCESS 0 -#define CREATE_DEVICE_FAILED -1 - -#ifdef HAVE_BLUETOOTH -static jfieldID field_mNativeData; - -static jmethodID method_onPropertyChanged; -static jmethodID method_onDevicePropertyChanged; -static jmethodID method_onDeviceFound; -static jmethodID method_onDeviceDisappeared; -static jmethodID method_onDeviceCreated; -static jmethodID method_onDeviceRemoved; -static jmethodID method_onDeviceDisconnectRequested; -static jmethodID method_onNetworkDeviceDisconnected; -static jmethodID method_onNetworkDeviceConnected; - -static jmethodID method_onCreatePairedDeviceResult; -static jmethodID method_onCreateDeviceResult; -static jmethodID method_onDiscoverServicesResult; -static jmethodID method_onGetDeviceServiceChannelResult; - -static jmethodID method_onRequestPinCode; -static jmethodID method_onRequestPasskey; -static jmethodID method_onRequestPasskeyConfirmation; -static jmethodID method_onRequestPairingConsent; -static jmethodID method_onDisplayPasskey; -static jmethodID method_onRequestOobData; -static jmethodID method_onAgentOutOfBandDataAvailable; -static jmethodID method_onAgentAuthorize; -static jmethodID method_onAgentCancel; - -static jmethodID method_onInputDevicePropertyChanged; -static jmethodID method_onInputDeviceConnectionResult; -static jmethodID method_onPanDevicePropertyChanged; -static jmethodID method_onPanDeviceConnectionResult; -static jmethodID method_onHealthDevicePropertyChanged; -static jmethodID method_onHealthDeviceChannelChanged; -static jmethodID method_onHealthDeviceConnectionResult; - -typedef event_loop_native_data_t native_data_t; - -#define EVENT_LOOP_REFS 10 - -static inline native_data_t * get_native_data(JNIEnv *env, jobject object) { - return (native_data_t *)(env->GetIntField(object, - field_mNativeData)); -} - -native_data_t *get_EventLoop_native_data(JNIEnv *env, jobject object) { - return get_native_data(env, object); -} - -#endif -static void classInitNative(JNIEnv* env, jclass clazz) { - ALOGV("%s", __FUNCTION__); - -#ifdef HAVE_BLUETOOTH - method_onPropertyChanged = env->GetMethodID(clazz, "onPropertyChanged", - "([Ljava/lang/String;)V"); - method_onDevicePropertyChanged = env->GetMethodID(clazz, - "onDevicePropertyChanged", - "(Ljava/lang/String;[Ljava/lang/String;)V"); - method_onDeviceFound = env->GetMethodID(clazz, "onDeviceFound", - "(Ljava/lang/String;[Ljava/lang/String;)V"); - method_onDeviceDisappeared = env->GetMethodID(clazz, "onDeviceDisappeared", - "(Ljava/lang/String;)V"); - method_onDeviceCreated = env->GetMethodID(clazz, "onDeviceCreated", "(Ljava/lang/String;)V"); - method_onDeviceRemoved = env->GetMethodID(clazz, "onDeviceRemoved", "(Ljava/lang/String;)V"); - method_onDeviceDisconnectRequested = env->GetMethodID(clazz, "onDeviceDisconnectRequested", - "(Ljava/lang/String;)V"); - method_onNetworkDeviceConnected = env->GetMethodID(clazz, "onNetworkDeviceConnected", - "(Ljava/lang/String;Ljava/lang/String;I)V"); - method_onNetworkDeviceDisconnected = env->GetMethodID(clazz, "onNetworkDeviceDisconnected", - "(Ljava/lang/String;)V"); - - method_onCreatePairedDeviceResult = env->GetMethodID(clazz, "onCreatePairedDeviceResult", - "(Ljava/lang/String;I)V"); - method_onCreateDeviceResult = env->GetMethodID(clazz, "onCreateDeviceResult", - "(Ljava/lang/String;I)V"); - method_onDiscoverServicesResult = env->GetMethodID(clazz, "onDiscoverServicesResult", - "(Ljava/lang/String;Z)V"); - - method_onAgentAuthorize = env->GetMethodID(clazz, "onAgentAuthorize", - "(Ljava/lang/String;Ljava/lang/String;I)V"); - method_onAgentOutOfBandDataAvailable = env->GetMethodID(clazz, "onAgentOutOfBandDataAvailable", - "(Ljava/lang/String;)Z"); - method_onAgentCancel = env->GetMethodID(clazz, "onAgentCancel", "()V"); - method_onRequestPinCode = env->GetMethodID(clazz, "onRequestPinCode", - "(Ljava/lang/String;I)V"); - method_onRequestPasskey = env->GetMethodID(clazz, "onRequestPasskey", - "(Ljava/lang/String;I)V"); - method_onRequestPasskeyConfirmation = env->GetMethodID(clazz, "onRequestPasskeyConfirmation", - "(Ljava/lang/String;II)V"); - method_onRequestPairingConsent = env->GetMethodID(clazz, "onRequestPairingConsent", - "(Ljava/lang/String;I)V"); - method_onDisplayPasskey = env->GetMethodID(clazz, "onDisplayPasskey", - "(Ljava/lang/String;II)V"); - method_onInputDevicePropertyChanged = env->GetMethodID(clazz, "onInputDevicePropertyChanged", - "(Ljava/lang/String;[Ljava/lang/String;)V"); - method_onInputDeviceConnectionResult = env->GetMethodID(clazz, "onInputDeviceConnectionResult", - "(Ljava/lang/String;I)V"); - method_onPanDevicePropertyChanged = env->GetMethodID(clazz, "onPanDevicePropertyChanged", - "(Ljava/lang/String;[Ljava/lang/String;)V"); - method_onPanDeviceConnectionResult = env->GetMethodID(clazz, "onPanDeviceConnectionResult", - "(Ljava/lang/String;I)V"); - method_onHealthDeviceConnectionResult = env->GetMethodID(clazz, - "onHealthDeviceConnectionResult", - "(II)V"); - method_onHealthDevicePropertyChanged = env->GetMethodID(clazz, "onHealthDevicePropertyChanged", - "(Ljava/lang/String;[Ljava/lang/String;)V"); - method_onHealthDeviceChannelChanged = env->GetMethodID(clazz, "onHealthDeviceChannelChanged", - "(Ljava/lang/String;Ljava/lang/String;Z)V"); - method_onRequestOobData = env->GetMethodID(clazz, "onRequestOobData", - "(Ljava/lang/String;I)V"); - - field_mNativeData = env->GetFieldID(clazz, "mNativeData", "I"); -#endif -} - -static void initializeNativeDataNative(JNIEnv* env, jobject object) { - ALOGV("%s", __FUNCTION__); -#ifdef HAVE_BLUETOOTH - native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t)); - if (NULL == nat) { - ALOGE("%s: out of memory!", __FUNCTION__); - return; - } - - pthread_mutex_init(&(nat->thread_mutex), NULL); - - env->SetIntField(object, field_mNativeData, (jint)nat); - - { - DBusError err; - dbus_error_init(&err); - dbus_threads_init_default(); - nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); - if (dbus_error_is_set(&err)) { - ALOGE("%s: Could not get onto the system bus!", __FUNCTION__); - dbus_error_free(&err); - } - dbus_connection_set_exit_on_disconnect(nat->conn, FALSE); - } -#endif -} - -static void cleanupNativeDataNative(JNIEnv* env, jobject object) { - ALOGV("%s", __FUNCTION__); -#ifdef HAVE_BLUETOOTH - native_data_t *nat = - (native_data_t *)env->GetIntField(object, field_mNativeData); - - pthread_mutex_destroy(&(nat->thread_mutex)); - - if (nat) { - free(nat); - } -#endif -} - -#ifdef HAVE_BLUETOOTH -static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg, - void *data); -DBusHandlerResult agent_event_filter(DBusConnection *conn, - DBusMessage *msg, - void *data); -static int register_agent(native_data_t *nat, - const char *agent_path, const char *capabilities); - -static const DBusObjectPathVTable agent_vtable = { - NULL, agent_event_filter, NULL, NULL, NULL, NULL -}; - -static unsigned int unix_events_to_dbus_flags(short events) { - return (events & DBUS_WATCH_READABLE ? POLLIN : 0) | - (events & DBUS_WATCH_WRITABLE ? POLLOUT : 0) | - (events & DBUS_WATCH_ERROR ? POLLERR : 0) | - (events & DBUS_WATCH_HANGUP ? POLLHUP : 0); -} - -static short dbus_flags_to_unix_events(unsigned int flags) { - return (flags & POLLIN ? DBUS_WATCH_READABLE : 0) | - (flags & POLLOUT ? DBUS_WATCH_WRITABLE : 0) | - (flags & POLLERR ? DBUS_WATCH_ERROR : 0) | - (flags & POLLHUP ? DBUS_WATCH_HANGUP : 0); -} - -static jboolean setUpEventLoop(native_data_t *nat) { - ALOGV("%s", __FUNCTION__); - - if (nat != NULL && nat->conn != NULL) { - dbus_threads_init_default(); - DBusError err; - dbus_error_init(&err); - - const char *agent_path = "/android/bluetooth/agent"; - const char *capabilities = "DisplayYesNo"; - if (register_agent(nat, agent_path, capabilities) < 0) { - dbus_connection_unregister_object_path (nat->conn, agent_path); - return JNI_FALSE; - } - - // Add a filter for all incoming messages - if (!dbus_connection_add_filter(nat->conn, event_filter, nat, NULL)){ - return JNI_FALSE; - } - - // Set which messages will be processed by this dbus connection - dbus_bus_add_match(nat->conn, - "type='signal',interface='org.freedesktop.DBus'", - &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='" 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='" BLUEZ_DBUS_BASE_IFC ".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='" BLUEZ_DBUS_BASE_IFC ".Input'", - &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='" BLUEZ_DBUS_BASE_IFC ".Network'", - &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='" BLUEZ_DBUS_BASE_IFC ".NetworkServer'", - &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='" BLUEZ_DBUS_BASE_IFC ".HealthDevice'", - &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.AudioSink'", - &err); - if (dbus_error_is_set(&err)) { - LOG_AND_FREE_DBUS_ERROR(&err); - return JNI_FALSE; - } - - return JNI_TRUE; - } - return JNI_FALSE; -} - - -const char * get_adapter_path(DBusConnection *conn) { - DBusMessage *msg = NULL, *reply = NULL; - DBusError err; - const char *device_path = NULL; - int attempt = 0; - - for (attempt = 0; attempt < 1000 && reply == NULL; attempt ++) { - msg = dbus_message_new_method_call("org.bluez", "/", - "org.bluez.Manager", "DefaultAdapter"); - if (!msg) { - ALOGE("%s: Can't allocate new method call for get_adapter_path!", - __FUNCTION__); - return NULL; - } - dbus_message_append_args(msg, DBUS_TYPE_INVALID); - dbus_error_init(&err); - reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err); - - if (!reply) { - if (dbus_error_is_set(&err)) { - if (dbus_error_has_name(&err, - "org.freedesktop.DBus.Error.ServiceUnknown")) { - // bluetoothd is still down, retry - LOG_AND_FREE_DBUS_ERROR(&err); - usleep(10000); // 10 ms - continue; - } else { - // Some other error we weren't expecting - LOG_AND_FREE_DBUS_ERROR(&err); - } - } - goto failed; - } - } - if (attempt == 1000) { - ALOGE("Time out while trying to get Adapter path, is bluetoothd up ?"); - goto failed; - } - - if (!dbus_message_get_args(reply, &err, DBUS_TYPE_OBJECT_PATH, - &device_path, DBUS_TYPE_INVALID) - || !device_path){ - if (dbus_error_is_set(&err)) { - LOG_AND_FREE_DBUS_ERROR(&err); - } - goto failed; - } - dbus_message_unref(msg); - return device_path; - -failed: - dbus_message_unref(msg); - return NULL; -} - -static int register_agent(native_data_t *nat, - const char * agent_path, const char * capabilities) -{ - DBusMessage *msg, *reply; - DBusError err; - dbus_bool_t oob = TRUE; - - if (!dbus_connection_register_object_path(nat->conn, agent_path, - &agent_vtable, nat)) { - ALOGE("%s: Can't register object path %s for agent!", - __FUNCTION__, agent_path); - return -1; - } - - nat->adapter = get_adapter_path(nat->conn); - if (nat->adapter == NULL) { - return -1; - } - msg = dbus_message_new_method_call("org.bluez", nat->adapter, - "org.bluez.Adapter", "RegisterAgent"); - if (!msg) { - ALOGE("%s: Can't allocate new method call for agent!", - __FUNCTION__); - return -1; - } - dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path, - DBUS_TYPE_STRING, &capabilities, - DBUS_TYPE_INVALID); - - dbus_error_init(&err); - reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err); - dbus_message_unref(msg); - - if (!reply) { - ALOGE("%s: Can't register agent!", __FUNCTION__); - if (dbus_error_is_set(&err)) { - LOG_AND_FREE_DBUS_ERROR(&err); - } - return -1; - } - - dbus_message_unref(reply); - dbus_connection_flush(nat->conn); - - return 0; -} - -static void tearDownEventLoop(native_data_t *nat) { - ALOGV("%s", __FUNCTION__); - if (nat != NULL && nat->conn != NULL) { - - DBusMessage *msg, *reply; - DBusError err; - dbus_error_init(&err); - const char * agent_path = "/android/bluetooth/agent"; - - msg = dbus_message_new_method_call("org.bluez", - nat->adapter, - "org.bluez.Adapter", - "UnregisterAgent"); - if (msg != NULL) { - dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path, - DBUS_TYPE_INVALID); - reply = dbus_connection_send_with_reply_and_block(nat->conn, - msg, -1, &err); - - if (!reply) { - if (dbus_error_is_set(&err)) { - LOG_AND_FREE_DBUS_ERROR(&err); - dbus_error_free(&err); - } - } else { - dbus_message_unref(reply); - } - dbus_message_unref(msg); - } else { - ALOGE("%s: Can't create new method call!", __FUNCTION__); - } - - dbus_connection_flush(nat->conn); - dbus_connection_unregister_object_path(nat->conn, agent_path); - - dbus_bus_remove_match(nat->conn, - "type='signal',interface='" BLUEZ_DBUS_BASE_IFC ".AudioSink'", - &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 ".Device'", - &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 ".Input'", - &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 ".Network'", - &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 ".NetworkServer'", - &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 ".HealthDevice'", - &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_bus_remove_match(nat->conn, - "type='signal',interface='org.freedesktop.DBus'", - &err); - if (dbus_error_is_set(&err)) { - LOG_AND_FREE_DBUS_ERROR(&err); - } - - dbus_connection_remove_filter(nat->conn, event_filter, nat); - } -} - - -#define EVENT_LOOP_EXIT 1 -#define EVENT_LOOP_ADD 2 -#define EVENT_LOOP_REMOVE 3 -#define EVENT_LOOP_WAKEUP 4 - -dbus_bool_t dbusAddWatch(DBusWatch *watch, void *data) { - native_data_t *nat = (native_data_t *)data; - - if (dbus_watch_get_enabled(watch)) { - // note that we can't just send the watch and inspect it later - // because we may get a removeWatch call before this data is reacted - // to by our eventloop and remove this watch.. reading the add first - // and then inspecting the recently deceased watch would be bad. - char control = EVENT_LOOP_ADD; - write(nat->controlFdW, &control, sizeof(char)); - - int fd = dbus_watch_get_fd(watch); - write(nat->controlFdW, &fd, sizeof(int)); - - unsigned int flags = dbus_watch_get_flags(watch); - write(nat->controlFdW, &flags, sizeof(unsigned int)); - - write(nat->controlFdW, &watch, sizeof(DBusWatch*)); - } - return true; -} - -void dbusRemoveWatch(DBusWatch *watch, void *data) { - native_data_t *nat = (native_data_t *)data; - - char control = EVENT_LOOP_REMOVE; - write(nat->controlFdW, &control, sizeof(char)); - - int fd = dbus_watch_get_fd(watch); - write(nat->controlFdW, &fd, sizeof(int)); - - unsigned int flags = dbus_watch_get_flags(watch); - write(nat->controlFdW, &flags, sizeof(unsigned int)); -} - -void dbusToggleWatch(DBusWatch *watch, void *data) { - if (dbus_watch_get_enabled(watch)) { - dbusAddWatch(watch, data); - } else { - dbusRemoveWatch(watch, data); - } -} - -void dbusWakeup(void *data) { - native_data_t *nat = (native_data_t *)data; - - char control = EVENT_LOOP_WAKEUP; - write(nat->controlFdW, &control, sizeof(char)); -} - -static void handleWatchAdd(native_data_t *nat) { - DBusWatch *watch; - int newFD; - unsigned int flags; - - read(nat->controlFdR, &newFD, sizeof(int)); - read(nat->controlFdR, &flags, sizeof(unsigned int)); - read(nat->controlFdR, &watch, sizeof(DBusWatch *)); - short events = dbus_flags_to_unix_events(flags); - - for (int y = 0; y<nat->pollMemberCount; y++) { - if ((nat->pollData[y].fd == newFD) && - (nat->pollData[y].events == events)) { - ALOGV("DBusWatch duplicate add"); - return; - } - } - if (nat->pollMemberCount == nat->pollDataSize) { - ALOGV("Bluetooth EventLoop poll struct growing"); - struct pollfd *temp = (struct pollfd *)malloc( - sizeof(struct pollfd) * (nat->pollMemberCount+1)); - if (!temp) { - return; - } - memcpy(temp, nat->pollData, sizeof(struct pollfd) * - nat->pollMemberCount); - free(nat->pollData); - nat->pollData = temp; - DBusWatch **temp2 = (DBusWatch **)malloc(sizeof(DBusWatch *) * - (nat->pollMemberCount+1)); - if (!temp2) { - return; - } - memcpy(temp2, nat->watchData, sizeof(DBusWatch *) * - nat->pollMemberCount); - free(nat->watchData); - nat->watchData = temp2; - nat->pollDataSize++; - } - nat->pollData[nat->pollMemberCount].fd = newFD; - nat->pollData[nat->pollMemberCount].revents = 0; - nat->pollData[nat->pollMemberCount].events = events; - nat->watchData[nat->pollMemberCount] = watch; - nat->pollMemberCount++; -} - -static void handleWatchRemove(native_data_t *nat) { - int removeFD; - unsigned int flags; - - read(nat->controlFdR, &removeFD, sizeof(int)); - read(nat->controlFdR, &flags, sizeof(unsigned int)); - short events = dbus_flags_to_unix_events(flags); - - for (int y = 0; y < nat->pollMemberCount; y++) { - if ((nat->pollData[y].fd == removeFD) && - (nat->pollData[y].events == events)) { - int newCount = --nat->pollMemberCount; - // copy the last live member over this one - nat->pollData[y].fd = nat->pollData[newCount].fd; - nat->pollData[y].events = nat->pollData[newCount].events; - nat->pollData[y].revents = nat->pollData[newCount].revents; - nat->watchData[y] = nat->watchData[newCount]; - return; - } - } - ALOGW("WatchRemove given with unknown watch"); -} - -static void *eventLoopMain(void *ptr) { - native_data_t *nat = (native_data_t *)ptr; - JNIEnv *env; - - JavaVMAttachArgs args; - char name[] = "BT EventLoop"; - args.version = nat->envVer; - args.name = name; - args.group = NULL; - - nat->vm->AttachCurrentThread(&env, &args); - - dbus_connection_set_watch_functions(nat->conn, dbusAddWatch, - dbusRemoveWatch, dbusToggleWatch, ptr, NULL); - dbus_connection_set_wakeup_main_function(nat->conn, dbusWakeup, ptr, NULL); - - nat->running = true; - - while (1) { - for (int i = 0; i < nat->pollMemberCount; i++) { - if (!nat->pollData[i].revents) { - continue; - } - if (nat->pollData[i].fd == nat->controlFdR) { - char data; - while (recv(nat->controlFdR, &data, sizeof(char), MSG_DONTWAIT) - != -1) { - switch (data) { - case EVENT_LOOP_EXIT: - { - dbus_connection_set_watch_functions(nat->conn, - NULL, NULL, NULL, NULL, NULL); - tearDownEventLoop(nat); - nat->vm->DetachCurrentThread(); - - int fd = nat->controlFdR; - nat->controlFdR = 0; - close(fd); - return NULL; - } - case EVENT_LOOP_ADD: - { - handleWatchAdd(nat); - break; - } - case EVENT_LOOP_REMOVE: - { - handleWatchRemove(nat); - break; - } - case EVENT_LOOP_WAKEUP: - { - // noop - break; - } - } - } - } else { - short events = nat->pollData[i].revents; - unsigned int flags = unix_events_to_dbus_flags(events); - dbus_watch_handle(nat->watchData[i], flags); - nat->pollData[i].revents = 0; - // can only do one - it may have caused a 'remove' - break; - } - } - while (dbus_connection_dispatch(nat->conn) == - DBUS_DISPATCH_DATA_REMAINS) { - } - - poll(nat->pollData, nat->pollMemberCount, -1); - } -} -#endif // HAVE_BLUETOOTH - -static jboolean startEventLoopNative(JNIEnv *env, jobject object) { - jboolean result = JNI_FALSE; -#ifdef HAVE_BLUETOOTH - event_loop_native_data_t *nat = get_native_data(env, object); - - pthread_mutex_lock(&(nat->thread_mutex)); - - nat->running = false; - - if (nat->pollData) { - ALOGW("trying to start EventLoop a second time!"); - pthread_mutex_unlock( &(nat->thread_mutex) ); - return JNI_FALSE; - } - - nat->pollData = (struct pollfd *)calloc( - DEFAULT_INITIAL_POLLFD_COUNT, sizeof(struct pollfd)); - if (!nat->pollData) { - ALOGE("out of memory error starting EventLoop!"); - goto done; - } - - nat->watchData = (DBusWatch **)calloc( - DEFAULT_INITIAL_POLLFD_COUNT, sizeof(DBusWatch *)); - if (!nat->watchData) { - ALOGE("out of memory error starting EventLoop!"); - goto done; - } - - nat->pollDataSize = DEFAULT_INITIAL_POLLFD_COUNT; - nat->pollMemberCount = 1; - - if (socketpair(AF_LOCAL, SOCK_STREAM, 0, &(nat->controlFdR))) { - ALOGE("Error getting BT control socket"); - goto done; - } - nat->pollData[0].fd = nat->controlFdR; - nat->pollData[0].events = POLLIN; - - env->GetJavaVM( &(nat->vm) ); - nat->envVer = env->GetVersion(); - - nat->me = env->NewGlobalRef(object); - - if (setUpEventLoop(nat) != JNI_TRUE) { - ALOGE("failure setting up Event Loop!"); - goto done; - } - - pthread_create(&(nat->thread), NULL, eventLoopMain, nat); - result = JNI_TRUE; - -done: - if (JNI_FALSE == result) { - if (nat->controlFdW) { - close(nat->controlFdW); - nat->controlFdW = 0; - } - if (nat->controlFdR) { - close(nat->controlFdR); - nat->controlFdR = 0; - } - if (nat->me) env->DeleteGlobalRef(nat->me); - nat->me = NULL; - if (nat->pollData) free(nat->pollData); - nat->pollData = NULL; - if (nat->watchData) free(nat->watchData); - nat->watchData = NULL; - nat->pollDataSize = 0; - nat->pollMemberCount = 0; - } - - pthread_mutex_unlock(&(nat->thread_mutex)); -#endif // HAVE_BLUETOOTH - return result; -} - -static void stopEventLoopNative(JNIEnv *env, jobject object) { -#ifdef HAVE_BLUETOOTH - native_data_t *nat = get_native_data(env, object); - - pthread_mutex_lock(&(nat->thread_mutex)); - if (nat->pollData) { - char data = EVENT_LOOP_EXIT; - ssize_t t = write(nat->controlFdW, &data, sizeof(char)); - void *ret; - pthread_join(nat->thread, &ret); - - env->DeleteGlobalRef(nat->me); - nat->me = NULL; - free(nat->pollData); - nat->pollData = NULL; - free(nat->watchData); - nat->watchData = NULL; - nat->pollDataSize = 0; - nat->pollMemberCount = 0; - - int fd = nat->controlFdW; - nat->controlFdW = 0; - close(fd); - } - nat->running = false; - pthread_mutex_unlock(&(nat->thread_mutex)); -#endif // HAVE_BLUETOOTH -} - -static jboolean isEventLoopRunningNative(JNIEnv *env, jobject object) { - jboolean result = JNI_FALSE; -#ifdef HAVE_BLUETOOTH - native_data_t *nat = get_native_data(env, object); - - pthread_mutex_lock(&(nat->thread_mutex)); - if (nat->running) { - result = JNI_TRUE; - } - pthread_mutex_unlock(&(nat->thread_mutex)); - -#endif // HAVE_BLUETOOTH - return result; -} - -#ifdef HAVE_BLUETOOTH -extern DBusHandlerResult a2dp_event_filter(DBusMessage *msg, JNIEnv *env); - -// Called by dbus during WaitForAndDispatchEventNative() -static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg, - void *data) { - native_data_t *nat; - JNIEnv *env; - DBusError err; - DBusHandlerResult ret; - - dbus_error_init(&err); - - nat = (native_data_t *)data; - nat->vm->GetEnv((void**)&env, nat->envVer); - if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL) { - ALOGV("%s: not interested (not a signal).", __FUNCTION__); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - ALOGV("%s: Received signal %s:%s from %s", __FUNCTION__, - dbus_message_get_interface(msg), dbus_message_get_member(msg), - dbus_message_get_path(msg)); - - env->PushLocalFrame(EVENT_LOOP_REFS); - if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "DeviceFound")) { - char *c_address; - DBusMessageIter iter; - jobjectArray str_array = NULL; - if (dbus_message_iter_init(msg, &iter)) { - dbus_message_iter_get_basic(&iter, &c_address); - if (dbus_message_iter_next(&iter)) - str_array = - parse_remote_device_properties(env, &iter); - } - if (str_array != NULL) { - env->CallVoidMethod(nat->me, - method_onDeviceFound, - env->NewStringUTF(c_address), - str_array); - } else - LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - goto success; - } else if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "DeviceDisappeared")) { - char *c_address; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_STRING, &c_address, - DBUS_TYPE_INVALID)) { - ALOGV("... address = %s", c_address); - env->CallVoidMethod(nat->me, method_onDeviceDisappeared, - env->NewStringUTF(c_address)); - } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - goto success; - } else if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "DeviceCreated")) { - char *c_object_path; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_OBJECT_PATH, &c_object_path, - DBUS_TYPE_INVALID)) { - ALOGV("... address = %s", c_object_path); - env->CallVoidMethod(nat->me, - method_onDeviceCreated, - env->NewStringUTF(c_object_path)); - } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - goto success; - } else if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "DeviceRemoved")) { - char *c_object_path; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_OBJECT_PATH, &c_object_path, - DBUS_TYPE_INVALID)) { - ALOGV("... Object Path = %s", c_object_path); - env->CallVoidMethod(nat->me, - method_onDeviceRemoved, - env->NewStringUTF(c_object_path)); - } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - goto success; - } else if (dbus_message_is_signal(msg, - "org.bluez.Adapter", - "PropertyChanged")) { - jobjectArray str_array = parse_adapter_property_change(env, msg); - if (str_array != NULL) { - /* Check if bluetoothd has (re)started, if so update the path. */ - jstring property =(jstring) env->GetObjectArrayElement(str_array, 0); - const char *c_property = env->GetStringUTFChars(property, NULL); - if (!strncmp(c_property, "Powered", strlen("Powered"))) { - jstring value = - (jstring) env->GetObjectArrayElement(str_array, 1); - const char *c_value = env->GetStringUTFChars(value, NULL); - if (!strncmp(c_value, "true", strlen("true"))) - nat->adapter = get_adapter_path(nat->conn); - env->ReleaseStringUTFChars(value, c_value); - } - env->ReleaseStringUTFChars(property, c_property); - - env->CallVoidMethod(nat->me, - method_onPropertyChanged, - str_array); - } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - goto success; - } else if (dbus_message_is_signal(msg, - "org.bluez.Device", - "PropertyChanged")) { - jobjectArray str_array = parse_remote_device_property_change(env, msg); - if (str_array != NULL) { - const char *remote_device_path = dbus_message_get_path(msg); - env->CallVoidMethod(nat->me, - method_onDevicePropertyChanged, - env->NewStringUTF(remote_device_path), - str_array); - } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - goto success; - } else if (dbus_message_is_signal(msg, - "org.bluez.Device", - "DisconnectRequested")) { - const char *remote_device_path = dbus_message_get_path(msg); - env->CallVoidMethod(nat->me, - method_onDeviceDisconnectRequested, - env->NewStringUTF(remote_device_path)); - goto success; - } else if (dbus_message_is_signal(msg, - "org.bluez.Input", - "PropertyChanged")) { - - jobjectArray str_array = - parse_input_property_change(env, msg); - if (str_array != NULL) { - const char *c_path = dbus_message_get_path(msg); - env->CallVoidMethod(nat->me, - method_onInputDevicePropertyChanged, - env->NewStringUTF(c_path), - str_array); - } else { - LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - } - goto success; - } else if (dbus_message_is_signal(msg, - "org.bluez.Network", - "PropertyChanged")) { - - jobjectArray str_array = - parse_pan_property_change(env, msg); - if (str_array != NULL) { - const char *c_path = dbus_message_get_path(msg); - env->CallVoidMethod(nat->me, - method_onPanDevicePropertyChanged, - env->NewStringUTF(c_path), - str_array); - } else { - LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - } - goto success; - } else if (dbus_message_is_signal(msg, - "org.bluez.NetworkServer", - "DeviceDisconnected")) { - char *c_address; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_STRING, &c_address, - DBUS_TYPE_INVALID)) { - env->CallVoidMethod(nat->me, - method_onNetworkDeviceDisconnected, - env->NewStringUTF(c_address)); - } else { - LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - } - goto success; - } else if (dbus_message_is_signal(msg, - "org.bluez.NetworkServer", - "DeviceConnected")) { - char *c_address; - char *c_iface; - uint16_t uuid; - - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_STRING, &c_address, - DBUS_TYPE_STRING, &c_iface, - DBUS_TYPE_UINT16, &uuid, - DBUS_TYPE_INVALID)) { - env->CallVoidMethod(nat->me, - method_onNetworkDeviceConnected, - env->NewStringUTF(c_address), - env->NewStringUTF(c_iface), - uuid); - } else { - LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - } - goto success; - } else if (dbus_message_is_signal(msg, - "org.bluez.HealthDevice", - "ChannelConnected")) { - const char *c_path = dbus_message_get_path(msg); - const char *c_channel_path; - jboolean exists = JNI_TRUE; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_OBJECT_PATH, &c_channel_path, - DBUS_TYPE_INVALID)) { - env->CallVoidMethod(nat->me, - method_onHealthDeviceChannelChanged, - env->NewStringUTF(c_path), - env->NewStringUTF(c_channel_path), - exists); - } else { - LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - } - goto success; - } else if (dbus_message_is_signal(msg, - "org.bluez.HealthDevice", - "ChannelDeleted")) { - - const char *c_path = dbus_message_get_path(msg); - const char *c_channel_path; - jboolean exists = JNI_FALSE; - if (dbus_message_get_args(msg, &err, - DBUS_TYPE_OBJECT_PATH, &c_channel_path, - DBUS_TYPE_INVALID)) { - env->CallVoidMethod(nat->me, - method_onHealthDeviceChannelChanged, - env->NewStringUTF(c_path), - env->NewStringUTF(c_channel_path), - exists); - } else { - LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - } - goto success; - } else if (dbus_message_is_signal(msg, - "org.bluez.HealthDevice", - "PropertyChanged")) { - jobjectArray str_array = - parse_health_device_property_change(env, msg); - if (str_array != NULL) { - const char *c_path = dbus_message_get_path(msg); - env->CallVoidMethod(nat->me, - method_onHealthDevicePropertyChanged, - env->NewStringUTF(c_path), - str_array); - } else { - LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); - } - goto success; - } - - ret = a2dp_event_filter(msg, env); - env->PopLocalFrame(NULL); - return ret; - -success: - env->PopLocalFrame(NULL); - return DBUS_HANDLER_RESULT_HANDLED; -} - -// Called by dbus during WaitForAndDispatchEventNative() -DBusHandlerResult agent_event_filter(DBusConnection *conn, - DBusMessage *msg, void *data) { - native_data_t *nat = (native_data_t *)data; - JNIEnv *env; - if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_METHOD_CALL) { - ALOGV("%s: not interested (not a method call).", __FUNCTION__); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - ALOGI("%s: Received method %s:%s", __FUNCTION__, - dbus_message_get_interface(msg), dbus_message_get_member(msg)); - - if (nat == NULL) return DBUS_HANDLER_RESULT_HANDLED; - - nat->vm->GetEnv((void**)&env, nat->envVer); - env->PushLocalFrame(EVENT_LOOP_REFS); - - if (dbus_message_is_method_call(msg, - "org.bluez.Agent", "Cancel")) { - env->CallVoidMethod(nat->me, method_onAgentCancel); - // reply - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) { - ALOGE("%s: Cannot create message reply\n", __FUNCTION__); - goto failure; - } - dbus_connection_send(nat->conn, reply, NULL); - dbus_message_unref(reply); - goto success; - - } else if (dbus_message_is_method_call(msg, - "org.bluez.Agent", "Authorize")) { - char *object_path; - const char *uuid; - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_OBJECT_PATH, &object_path, - DBUS_TYPE_STRING, &uuid, - DBUS_TYPE_INVALID)) { - ALOGE("%s: Invalid arguments for Authorize() method", __FUNCTION__); - goto failure; - } - - ALOGV("... object_path = %s", object_path); - ALOGV("... uuid = %s", uuid); - - dbus_message_ref(msg); // increment refcount because we pass to java - env->CallVoidMethod(nat->me, method_onAgentAuthorize, - env->NewStringUTF(object_path), env->NewStringUTF(uuid), - int(msg)); - - goto success; - } else if (dbus_message_is_method_call(msg, - "org.bluez.Agent", "OutOfBandAvailable")) { - char *object_path; - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_OBJECT_PATH, &object_path, - DBUS_TYPE_INVALID)) { - ALOGE("%s: Invalid arguments for OutOfBandData available() method", __FUNCTION__); - goto failure; - } - - ALOGV("... object_path = %s", object_path); - - bool available = - env->CallBooleanMethod(nat->me, method_onAgentOutOfBandDataAvailable, - env->NewStringUTF(object_path)); - - - // reply - if (available) { - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) { - ALOGE("%s: Cannot create message reply\n", __FUNCTION__); - goto failure; - } - dbus_connection_send(nat->conn, reply, NULL); - dbus_message_unref(reply); - } else { - DBusMessage *reply = dbus_message_new_error(msg, - "org.bluez.Error.DoesNotExist", "OutofBand data not available"); - if (!reply) { - ALOGE("%s: Cannot create message reply\n", __FUNCTION__); - goto failure; - } - dbus_connection_send(nat->conn, reply, NULL); - dbus_message_unref(reply); - } - goto success; - } else if (dbus_message_is_method_call(msg, - "org.bluez.Agent", "RequestPinCode")) { - char *object_path; - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_OBJECT_PATH, &object_path, - DBUS_TYPE_INVALID)) { - ALOGE("%s: Invalid arguments for RequestPinCode() method", __FUNCTION__); - goto failure; - } - - dbus_message_ref(msg); // increment refcount because we pass to java - env->CallVoidMethod(nat->me, method_onRequestPinCode, - env->NewStringUTF(object_path), - int(msg)); - goto success; - } else if (dbus_message_is_method_call(msg, - "org.bluez.Agent", "RequestPasskey")) { - char *object_path; - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_OBJECT_PATH, &object_path, - DBUS_TYPE_INVALID)) { - ALOGE("%s: Invalid arguments for RequestPasskey() method", __FUNCTION__); - goto failure; - } - - dbus_message_ref(msg); // increment refcount because we pass to java - env->CallVoidMethod(nat->me, method_onRequestPasskey, - env->NewStringUTF(object_path), - int(msg)); - goto success; - } else if (dbus_message_is_method_call(msg, - "org.bluez.Agent", "RequestOobData")) { - char *object_path; - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_OBJECT_PATH, &object_path, - DBUS_TYPE_INVALID)) { - ALOGE("%s: Invalid arguments for RequestOobData() method", __FUNCTION__); - goto failure; - } - - dbus_message_ref(msg); // increment refcount because we pass to java - env->CallVoidMethod(nat->me, method_onRequestOobData, - env->NewStringUTF(object_path), - int(msg)); - goto success; - } else if (dbus_message_is_method_call(msg, - "org.bluez.Agent", "DisplayPasskey")) { - char *object_path; - uint32_t passkey; - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_OBJECT_PATH, &object_path, - DBUS_TYPE_UINT32, &passkey, - DBUS_TYPE_INVALID)) { - ALOGE("%s: Invalid arguments for RequestPasskey() method", __FUNCTION__); - goto failure; - } - - dbus_message_ref(msg); // increment refcount because we pass to java - env->CallVoidMethod(nat->me, method_onDisplayPasskey, - env->NewStringUTF(object_path), - passkey, - int(msg)); - goto success; - } else if (dbus_message_is_method_call(msg, - "org.bluez.Agent", "RequestConfirmation")) { - char *object_path; - uint32_t passkey; - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_OBJECT_PATH, &object_path, - DBUS_TYPE_UINT32, &passkey, - DBUS_TYPE_INVALID)) { - ALOGE("%s: Invalid arguments for RequestConfirmation() method", __FUNCTION__); - goto failure; - } - - dbus_message_ref(msg); // increment refcount because we pass to java - env->CallVoidMethod(nat->me, method_onRequestPasskeyConfirmation, - env->NewStringUTF(object_path), - passkey, - int(msg)); - goto success; - } else if (dbus_message_is_method_call(msg, - "org.bluez.Agent", "RequestPairingConsent")) { - char *object_path; - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_OBJECT_PATH, &object_path, - DBUS_TYPE_INVALID)) { - ALOGE("%s: Invalid arguments for RequestPairingConsent() method", __FUNCTION__); - goto failure; - } - - dbus_message_ref(msg); // increment refcount because we pass to java - env->CallVoidMethod(nat->me, method_onRequestPairingConsent, - env->NewStringUTF(object_path), - int(msg)); - goto success; - } else if (dbus_message_is_method_call(msg, - "org.bluez.Agent", "Release")) { - // reply - DBusMessage *reply = dbus_message_new_method_return(msg); - if (!reply) { - ALOGE("%s: Cannot create message reply\n", __FUNCTION__); - goto failure; - } - dbus_connection_send(nat->conn, reply, NULL); - dbus_message_unref(reply); - goto success; - } else { - ALOGV("%s:%s is ignored", dbus_message_get_interface(msg), dbus_message_get_member(msg)); - } - -failure: - env->PopLocalFrame(NULL); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - -success: - env->PopLocalFrame(NULL); - return DBUS_HANDLER_RESULT_HANDLED; - -} -#endif - - -#ifdef HAVE_BLUETOOTH - -void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) { - ALOGV("%s", __FUNCTION__); - - native_data_t *nat = (native_data_t *)n; - const char *address = (const char *)user; - DBusError err; - dbus_error_init(&err); - JNIEnv *env; - jstring addr; - - nat->vm->GetEnv((void**)&env, nat->envVer); - - ALOGV("... address = %s", address); - - jint result = BOND_RESULT_SUCCESS; - if (dbus_set_error_from_message(&err, msg)) { - if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationFailed")) { - // Pins did not match, or remote device did not respond to pin - // request in time - ALOGV("... error = %s (%s)\n", err.name, err.message); - result = BOND_RESULT_AUTH_FAILED; - } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationRejected")) { - // We rejected pairing, or the remote side rejected pairing. This - // happens if either side presses 'cancel' at the pairing dialog. - ALOGV("... error = %s (%s)\n", err.name, err.message); - result = BOND_RESULT_AUTH_REJECTED; - } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationCanceled")) { - // Not sure if this happens - ALOGV("... error = %s (%s)\n", err.name, err.message); - result = BOND_RESULT_AUTH_CANCELED; - } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.ConnectionAttemptFailed")) { - // Other device is not responding at all - ALOGV("... error = %s (%s)\n", err.name, err.message); - result = BOND_RESULT_REMOTE_DEVICE_DOWN; - } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AlreadyExists")) { - // already bonded - ALOGV("... error = %s (%s)\n", err.name, err.message); - result = BOND_RESULT_SUCCESS; - } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.InProgress") && - !strcmp(err.message, "Bonding in progress")) { - ALOGV("... error = %s (%s)\n", err.name, err.message); - goto done; - } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.InProgress") && - !strcmp(err.message, "Discover in progress")) { - ALOGV("... error = %s (%s)\n", err.name, err.message); - result = BOND_RESULT_DISCOVERY_IN_PROGRESS; - } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.RepeatedAttempts")) { - ALOGV("... error = %s (%s)\n", err.name, err.message); - result = BOND_RESULT_REPEATED_ATTEMPTS; - } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationTimeout")) { - ALOGV("... error = %s (%s)\n", err.name, err.message); - result = BOND_RESULT_AUTH_TIMEOUT; - } else { - ALOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message); - result = BOND_RESULT_ERROR; - } - } - - addr = env->NewStringUTF(address); - env->CallVoidMethod(nat->me, - method_onCreatePairedDeviceResult, - addr, - result); - env->DeleteLocalRef(addr); -done: - dbus_error_free(&err); - free(user); -} - -void onCreateDeviceResult(DBusMessage *msg, void *user, void *n) { - ALOGV("%s", __FUNCTION__); - - native_data_t *nat = (native_data_t *)n; - const char *address= (const char *)user; - DBusError err; - dbus_error_init(&err); - JNIEnv *env; - nat->vm->GetEnv((void**)&env, nat->envVer); - - ALOGV("... Address = %s", address); - - jint result = CREATE_DEVICE_SUCCESS; - if (dbus_set_error_from_message(&err, msg)) { - if (dbus_error_has_name(&err, "org.bluez.Error.AlreadyExists")) { - result = CREATE_DEVICE_ALREADY_EXISTS; - } else { - result = CREATE_DEVICE_FAILED; - } - LOG_AND_FREE_DBUS_ERROR(&err); - } - jstring addr = env->NewStringUTF(address); - env->CallVoidMethod(nat->me, - method_onCreateDeviceResult, - addr, - result); - env->DeleteLocalRef(addr); - free(user); -} - -void onDiscoverServicesResult(DBusMessage *msg, void *user, void *n) { - ALOGV("%s", __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); - - ALOGV("... Device Path = %s", path); - - bool result = JNI_TRUE; - if (dbus_set_error_from_message(&err, msg)) { - LOG_AND_FREE_DBUS_ERROR(&err); - result = JNI_FALSE; - } - jstring jPath = env->NewStringUTF(path); - env->CallVoidMethod(nat->me, - method_onDiscoverServicesResult, - jPath, - result); - env->DeleteLocalRef(jPath); - free(user); -} - -void onGetDeviceServiceChannelResult(DBusMessage *msg, void *user, void *n) { - ALOGV("%s", __FUNCTION__); - - const char *address = (const char *) user; - native_data_t *nat = (native_data_t *) n; - - DBusError err; - dbus_error_init(&err); - JNIEnv *env; - nat->vm->GetEnv((void**)&env, nat->envVer); - - jint channel = -2; - - ALOGV("... address = %s", address); - - if (dbus_set_error_from_message(&err, msg) || - !dbus_message_get_args(msg, &err, - DBUS_TYPE_INT32, &channel, - DBUS_TYPE_INVALID)) { - ALOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message); - dbus_error_free(&err); - } - -done: - jstring addr = env->NewStringUTF(address); - env->CallVoidMethod(nat->me, - method_onGetDeviceServiceChannelResult, - addr, - channel); - env->DeleteLocalRef(addr); - free(user); -} - -void onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *n) { - ALOGV("%s", __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); - - jint result = INPUT_OPERATION_SUCCESS; - if (dbus_set_error_from_message(&err, msg)) { - if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) { - result = INPUT_CONNECT_FAILED_ATTEMPT_FAILED; - } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".AlreadyConnected")) { - result = INPUT_CONNECT_FAILED_ALREADY_CONNECTED; - } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) { - // TODO():This is flaky, need to change Bluez to add new error codes - if (!strcmp(err.message, "Transport endpoint is not connected")) { - result = INPUT_DISCONNECT_FAILED_NOT_CONNECTED; - } else { - result = INPUT_OPERATION_GENERIC_FAILURE; - } - } else { - result = INPUT_OPERATION_GENERIC_FAILURE; - } - LOG_AND_FREE_DBUS_ERROR(&err); - } - - ALOGV("... Device Path = %s, result = %d", path, result); - jstring jPath = env->NewStringUTF(path); - env->CallVoidMethod(nat->me, - method_onInputDeviceConnectionResult, - jPath, - result); - env->DeleteLocalRef(jPath); - free(user); -} - -void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *n) { - ALOGV("%s", __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); - - jint result = PAN_OPERATION_SUCCESS; - if (dbus_set_error_from_message(&err, msg)) { - if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) { - result = PAN_CONNECT_FAILED_ATTEMPT_FAILED; - } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) { - // TODO():This is flaky, need to change Bluez to add new error codes - if (!strcmp(err.message, "Device already connected")) { - result = PAN_CONNECT_FAILED_ALREADY_CONNECTED; - } else if (!strcmp(err.message, "Device not connected")) { - result = PAN_DISCONNECT_FAILED_NOT_CONNECTED; - } else { - result = PAN_OPERATION_GENERIC_FAILURE; - } - } else { - result = PAN_OPERATION_GENERIC_FAILURE; - } - LOG_AND_FREE_DBUS_ERROR(&err); - } - - ALOGV("... Pan Device Path = %s, result = %d", path, result); - jstring jPath = env->NewStringUTF(path); - env->CallVoidMethod(nat->me, - method_onPanDeviceConnectionResult, - jPath, - result); - env->DeleteLocalRef(jPath); - free(user); -} - -void onHealthDeviceConnectionResult(DBusMessage *msg, void *user, void *n) { - ALOGV("%s", __FUNCTION__); - - native_data_t *nat = (native_data_t *)n; - DBusError err; - dbus_error_init(&err); - JNIEnv *env; - nat->vm->GetEnv((void**)&env, nat->envVer); - - jint result = HEALTH_OPERATION_SUCCESS; - if (dbus_set_error_from_message(&err, msg)) { - if (!strcmp(err.name, BLUEZ_ERROR_IFC ".InvalidArgs")) { - result = HEALTH_OPERATION_INVALID_ARGS; - } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".HealthError")) { - result = HEALTH_OPERATION_ERROR; - } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotFound")) { - result = HEALTH_OPERATION_NOT_FOUND; - } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotAllowed")) { - result = HEALTH_OPERATION_NOT_ALLOWED; - } else { - result = HEALTH_OPERATION_GENERIC_FAILURE; - } - LOG_AND_FREE_DBUS_ERROR(&err); - } - - jint code = *(int *) user; - ALOGV("... Health Device Code = %d, result = %d", code, result); - env->CallVoidMethod(nat->me, - method_onHealthDeviceConnectionResult, - code, - result); - free(user); -} -#endif - -static JNINativeMethod sMethods[] = { - /* name, signature, funcPtr */ - {"classInitNative", "()V", (void *)classInitNative}, - {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative}, - {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative}, - {"startEventLoopNative", "()V", (void *)startEventLoopNative}, - {"stopEventLoopNative", "()V", (void *)stopEventLoopNative}, - {"isEventLoopRunningNative", "()Z", (void *)isEventLoopRunningNative} -}; - -int register_android_server_BluetoothEventLoop(JNIEnv *env) { - return AndroidRuntime::registerNativeMethods(env, - "android/server/BluetoothEventLoop", sMethods, NELEM(sMethods)); -} - -} /* namespace android */ |