/*
** 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) {
        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) {
    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) {
            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;
    dbus_bool_t oob = TRUE;

    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) {
    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 {
             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='"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;
        }
    }
    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);
    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) {
        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) {
        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) {
            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;
        }

        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)) {
            LOGE("%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) {
                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.DoesNotExist", "OutofBand data not available");
            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", "RequestOobData")) {
        char *object_path;
        if (!dbus_message_get_args(msg, NULL,
                                   DBUS_TYPE_OBJECT_PATH, &object_path,
                                   DBUS_TYPE_INVALID)) {
            LOGE("%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)) {
            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 {
        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 {
            LOGE("%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)) {
        LOGE("%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 */
