summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org>2012-10-15 01:07:03 +0200
committerBernhard Rosenkränzer <Bernhard.Rosenkranzer@linaro.org>2013-12-12 03:42:01 +0100
commit5546ab4a88a00b6da15821d037d993818a496e83 (patch)
tree79a1ba1c6793ef5e3c5995fa8a44e52fb85c29fb
parent7c6a81658938d4723abc2c6ef8bd8da0ff706c4c (diff)
downloadbase-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.cpp2
-rw-r--r--core/jni/android_server_BluetoothEventLoop.cpp1585
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 */