/*
** 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_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_onAgentAuthorize;
static jmethodID method_onAgentCancel;

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) {
    LOGV(__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_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;)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");

    field_mNativeData = env->GetFieldID(clazz, "mNativeData", "I");
#endif
}

static void initializeNativeDataNative(JNIEnv* env, jobject object) {
    LOGV(__FUNCTION__);
#ifdef HAVE_BLUETOOTH
    native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
    if (NULL == nat) {
        LOGE("%s: out of memory!", __FUNCTION__);
        return;
    }
    memset(nat, 0, sizeof(native_data_t));

    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)) {
            LOGE("%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) {
    LOGV(__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) {
    LOGV(__FUNCTION__);

    if (nat != NULL && nat->conn != NULL) {
        dbus_threads_init_default();
        DBusError err;
        dbus_error_init(&err);

        // 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='org.bluez.AudioSink'",
                &err);
        if (dbus_error_is_set(&err)) {
            LOG_AND_FREE_DBUS_ERROR(&err);
            return JNI_FALSE;
        }

        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;
        }
        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) {
            LOGE("%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) {
        LOGE("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;

    if (!dbus_connection_register_object_path(nat->conn, agent_path,
            &agent_vtable, nat)) {
        LOGE("%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) {
        LOGE("%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) {
        LOGE("%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) {
    LOGV(__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 {
             LOGE("%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='org.bluez.AudioSink'",
                &err);
        if (dbus_error_is_set(&err)) {
            LOG_AND_FREE_DBUS_ERROR(&err);
        }
        dbus_bus_remove_match(nat->conn,
                "type='signal',interface='org.bluez.audio.Device'",
                &err);
        if (dbus_error_is_set(&err)) {
            LOG_AND_FREE_DBUS_ERROR(&err);
        }
        dbus_bus_remove_match(nat->conn,
                "type='signal',interface='org.bluez.audio.Manager'",
                &err);
        if (dbus_error_is_set(&err)) {
            LOG_AND_FREE_DBUS_ERROR(&err);
        }
        dbus_bus_remove_match(nat->conn,
                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Adapter'",
                &err);
        if (dbus_error_is_set(&err)) {
            LOG_AND_FREE_DBUS_ERROR(&err);
        }
        dbus_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

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);
    }
}

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)) {
            LOGV("DBusWatch duplicate add");
            return;
        }
    }
    if (nat->pollMemberCount == nat->pollDataSize) {
        LOGV("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;
        }
    }
    LOGW("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);

    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;
                    }
                    }
                }
            } 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) {
        LOGW("trying to start EventLoop a second time!");
        pthread_mutex_unlock( &(nat->thread_mutex) );
        return JNI_FALSE;
    }

    nat->pollData = (struct pollfd *)malloc(sizeof(struct pollfd) *
            DEFAULT_INITIAL_POLLFD_COUNT);
    if (!nat->pollData) {
        LOGE("out of memory error starting EventLoop!");
        goto done;
    }

    nat->watchData = (DBusWatch **)malloc(sizeof(DBusWatch *) *
            DEFAULT_INITIAL_POLLFD_COUNT);
    if (!nat->watchData) {
        LOGE("out of memory error starting EventLoop!");
        goto done;
    }

    memset(nat->pollData, 0, sizeof(struct pollfd) *
            DEFAULT_INITIAL_POLLFD_COUNT);
    memset(nat->watchData, 0, sizeof(DBusWatch *) *
            DEFAULT_INITIAL_POLLFD_COUNT);
    nat->pollDataSize = DEFAULT_INITIAL_POLLFD_COUNT;
    nat->pollMemberCount = 1;

    if (socketpair(AF_LOCAL, SOCK_STREAM, 0, &(nat->controlFdR))) {
        LOGE("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) {
        LOGE("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) {
        LOGV("%s: not interested (not a signal).", __FUNCTION__);
        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }

    LOGE("%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)) {
            LOGV("... 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)) {
            LOGV("... 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)) {
           LOGV("... 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;
    }

    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) {
        LOGV("%s: not interested (not a method call).", __FUNCTION__);
        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }
    LOGI("%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) {
            LOGE("%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)) {
            LOGE("%s: Invalid arguments for Authorize() method", __FUNCTION__);
            goto failure;
        }

        LOGV("... object_path = %s", object_path);
        LOGV("... uuid = %s", uuid);

        bool auth_granted =
            env->CallBooleanMethod(nat->me, method_onAgentAuthorize,
                env->NewStringUTF(object_path), env->NewStringUTF(uuid));

        // reply
        if (auth_granted) {
            DBusMessage *reply = dbus_message_new_method_return(msg);
            if (!reply) {
                LOGE("%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.Rejected", "Authorization rejected");
            if (!reply) {
                LOGE("%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)) {
            LOGE("%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)) {
            LOGE("%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", "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)) {
            LOGE("%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)) {
            LOGE("%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)) {
            LOGE("%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) {
            LOGE("%s: Cannot create message reply\n", __FUNCTION__);
            goto failure;
        }
        dbus_connection_send(nat->conn, reply, NULL);
        dbus_message_unref(reply);
        goto success;
    } else {
        LOGV("%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
//TODO: Unify result codes in a header
#define BOND_RESULT_ERROR -1000
#define BOND_RESULT_SUCCESS 0
#define BOND_RESULT_AUTH_FAILED 1
#define BOND_RESULT_AUTH_REJECTED 2
#define BOND_RESULT_AUTH_CANCELED 3
#define BOND_RESULT_REMOTE_DEVICE_DOWN 4
#define BOND_RESULT_DISCOVERY_IN_PROGRESS 5
#define BOND_RESULT_AUTH_TIMEOUT 6
#define BOND_RESULT_REPEATED_ATTEMPTS 7

void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) {
    LOGV(__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);

    LOGV("... 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
            LOGV("... 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.
            LOGV("... 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
            LOGV("... 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
            LOGV("... 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
            LOGV("... 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")) {
            LOGV("... 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")) {
            LOGV("... 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")) {
            LOGV("... error = %s (%s)\n", err.name, err.message);
            result = BOND_RESULT_REPEATED_ATTEMPTS;
        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationTimeout")) {
            LOGV("... error = %s (%s)\n", err.name, err.message);
            result = BOND_RESULT_AUTH_TIMEOUT;
        } else {
            LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
            result = BOND_RESULT_ERROR;
        }
    }

    env->CallVoidMethod(nat->me,
                        method_onCreatePairedDeviceResult,
                        env->NewStringUTF(address),
                        result);
done:
    dbus_error_free(&err);
    free(user);
}

void onCreateDeviceResult(DBusMessage *msg, void *user, void *n) {
    LOGV(__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);

    LOGV("... 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);
    }
    env->CallVoidMethod(nat->me,
                        method_onCreateDeviceResult,
                        env->NewStringUTF(address),
                        result);
    free(user);
}

void onDiscoverServicesResult(DBusMessage *msg, void *user, void *n) {
    LOGV(__FUNCTION__);

    native_data_t *nat = (native_data_t *)n;
    const char *path = (const char *)user;
    DBusError err;
    dbus_error_init(&err);
    JNIEnv *env;
    nat->vm->GetEnv((void**)&env, nat->envVer);

    LOGV("... 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;
    }
    env->CallVoidMethod(nat->me,
                        method_onDiscoverServicesResult,
                        env->NewStringUTF(path),
                        result);
    free(user);
}

void onGetDeviceServiceChannelResult(DBusMessage *msg, void *user, void *n) {
    LOGV(__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;

    LOGV("... address = %s", address);

    if (dbus_set_error_from_message(&err, msg) ||
        !dbus_message_get_args(msg, &err,
                               DBUS_TYPE_INT32, &channel,
                               DBUS_TYPE_INVALID)) {
        LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
        dbus_error_free(&err);
    }

done:
    env->CallVoidMethod(nat->me,
                        method_onGetDeviceServiceChannelResult,
                        env->NewStringUTF(address),
                        channel);
    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 */
