19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2008, The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "BluetoothEventLoop.cpp"
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_bluetooth_common.h"
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_runtime/AndroidRuntime.h"
2128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#include "cutils/sockets.h"
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h"
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h"
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/Log.h"
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/misc.h"
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h>
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <errno.h>
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h>
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <dbus/dbus.h>
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3916fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly#define CREATE_DEVICE_ALREADY_EXISTS 1
4016fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly#define CREATE_DEVICE_SUCCESS 0
4116fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly#define CREATE_DEVICE_FAILED -1
4216fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID field_mNativeData;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
46d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onPropertyChanged;
47d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onDevicePropertyChanged;
48d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onDeviceFound;
49d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onDeviceDisappeared;
50d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onDeviceCreated;
51d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onDeviceRemoved;
525e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganeshstatic jmethodID method_onDeviceDisconnectRequested;
53c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganeshstatic jmethodID method_onNetworkDeviceDisconnected;
54c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganeshstatic jmethodID method_onNetworkDeviceConnected;
55d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
56d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onCreatePairedDeviceResult;
571caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganeshstatic jmethodID method_onCreateDeviceResult;
581caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganeshstatic jmethodID method_onDiscoverServicesResult;
59d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onGetDeviceServiceChannelResult;
60d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
61d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onRequestPinCode;
62b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganeshstatic jmethodID method_onRequestPasskey;
6332d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganeshstatic jmethodID method_onRequestPasskeyConfirmation;
6432d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganeshstatic jmethodID method_onRequestPairingConsent;
6532d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganeshstatic jmethodID method_onDisplayPasskey;
66cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganeshstatic jmethodID method_onRequestOobData;
67cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganeshstatic jmethodID method_onAgentOutOfBandDataAvailable;
68d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onAgentAuthorize;
69d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic jmethodID method_onAgentCancel;
70c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project
71545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganeshstatic jmethodID method_onInputDevicePropertyChanged;
72de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganeshstatic jmethodID method_onInputDeviceConnectionResult;
736fdd0c6274c81b337ad35b70480f881daf7354c3Danica Changstatic jmethodID method_onPanDevicePropertyChanged;
746fdd0c6274c81b337ad35b70480f881daf7354c3Danica Changstatic jmethodID method_onPanDeviceConnectionResult;
752ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganeshstatic jmethodID method_onHealthDevicePropertyChanged;
762ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganeshstatic jmethodID method_onHealthDeviceChannelChanged;
77b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganeshstatic jmethodID method_onHealthDeviceConnectionResult;
78545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef event_loop_native_data_t native_data_t;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
816d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh#define EVENT_LOOP_REFS 10
826d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (native_data_t *)(env->GetIntField(object,
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                 field_mNativeData));
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltnative_data_t *get_EventLoop_native_data(JNIEnv *env, jobject object) {
8928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    return get_native_data(env, object);
9028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
9128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void classInitNative(JNIEnv* env, jclass clazz) {
9471f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("%s", __FUNCTION__);
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
97d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onPropertyChanged = env->GetMethodID(clazz, "onPropertyChanged",
98d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                "([Ljava/lang/String;)V");
99d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onDevicePropertyChanged = env->GetMethodID(clazz,
100d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                      "onDevicePropertyChanged",
101d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                      "(Ljava/lang/String;[Ljava/lang/String;)V");
102d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onDeviceFound = env->GetMethodID(clazz, "onDeviceFound",
103d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                            "(Ljava/lang/String;[Ljava/lang/String;)V");
104d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onDeviceDisappeared = env->GetMethodID(clazz, "onDeviceDisappeared",
105d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                  "(Ljava/lang/String;)V");
106d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onDeviceCreated = env->GetMethodID(clazz, "onDeviceCreated", "(Ljava/lang/String;)V");
107d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onDeviceRemoved = env->GetMethodID(clazz, "onDeviceRemoved", "(Ljava/lang/String;)V");
1085e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh    method_onDeviceDisconnectRequested = env->GetMethodID(clazz, "onDeviceDisconnectRequested",
1095e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh                                                        "(Ljava/lang/String;)V");
110c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh    method_onNetworkDeviceConnected = env->GetMethodID(clazz, "onNetworkDeviceConnected",
111707952ecd4b6cae25aabcf51f94d702a65847e9eJaikumar Ganesh                                                     "(Ljava/lang/String;Ljava/lang/String;I)V");
112c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh    method_onNetworkDeviceDisconnected = env->GetMethodID(clazz, "onNetworkDeviceDisconnected",
113c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                                              "(Ljava/lang/String;)V");
114d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
115d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onCreatePairedDeviceResult = env->GetMethodID(clazz, "onCreatePairedDeviceResult",
116d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                                         "(Ljava/lang/String;I)V");
1171caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    method_onCreateDeviceResult = env->GetMethodID(clazz, "onCreateDeviceResult",
11816fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly                                                         "(Ljava/lang/String;I)V");
1191caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    method_onDiscoverServicesResult = env->GetMethodID(clazz, "onDiscoverServicesResult",
1201caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                                                         "(Ljava/lang/String;Z)V");
121d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
122d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onAgentAuthorize = env->GetMethodID(clazz, "onAgentAuthorize",
123a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie                                               "(Ljava/lang/String;Ljava/lang/String;I)V");
124cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh    method_onAgentOutOfBandDataAvailable = env->GetMethodID(clazz, "onAgentOutOfBandDataAvailable",
125cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                                               "(Ljava/lang/String;)Z");
126d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onAgentCancel = env->GetMethodID(clazz, "onAgentCancel", "()V");
127d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    method_onRequestPinCode = env->GetMethodID(clazz, "onRequestPinCode",
128d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                               "(Ljava/lang/String;I)V");
129b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    method_onRequestPasskey = env->GetMethodID(clazz, "onRequestPasskey",
130b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                               "(Ljava/lang/String;I)V");
13132d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    method_onRequestPasskeyConfirmation = env->GetMethodID(clazz, "onRequestPasskeyConfirmation",
13232d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                               "(Ljava/lang/String;II)V");
13332d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    method_onRequestPairingConsent = env->GetMethodID(clazz, "onRequestPairingConsent",
13432d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                               "(Ljava/lang/String;I)V");
13532d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    method_onDisplayPasskey = env->GetMethodID(clazz, "onDisplayPasskey",
136b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                               "(Ljava/lang/String;II)V");
137545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    method_onInputDevicePropertyChanged = env->GetMethodID(clazz, "onInputDevicePropertyChanged",
1386fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                                               "(Ljava/lang/String;[Ljava/lang/String;)V");
139de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    method_onInputDeviceConnectionResult = env->GetMethodID(clazz, "onInputDeviceConnectionResult",
140fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh                                               "(Ljava/lang/String;I)V");
1416fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    method_onPanDevicePropertyChanged = env->GetMethodID(clazz, "onPanDevicePropertyChanged",
1426fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                                               "(Ljava/lang/String;[Ljava/lang/String;)V");
1436fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    method_onPanDeviceConnectionResult = env->GetMethodID(clazz, "onPanDeviceConnectionResult",
144fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh                                               "(Ljava/lang/String;I)V");
145b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    method_onHealthDeviceConnectionResult = env->GetMethodID(clazz,
146b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh                                                             "onHealthDeviceConnectionResult",
147b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh                                                             "(II)V");
1482ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh    method_onHealthDevicePropertyChanged = env->GetMethodID(clazz, "onHealthDevicePropertyChanged",
1492ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                               "(Ljava/lang/String;[Ljava/lang/String;)V");
1502ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh    method_onHealthDeviceChannelChanged = env->GetMethodID(clazz, "onHealthDeviceChannelChanged",
1512ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                               "(Ljava/lang/String;Ljava/lang/String;Z)V");
152cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh    method_onRequestOobData = env->GetMethodID(clazz, "onRequestOobData",
153cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                                               "(Ljava/lang/String;I)V");
154c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    field_mNativeData = env->GetFieldID(clazz, "mNativeData", "I");
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void initializeNativeDataNative(JNIEnv* env, jobject object) {
16071f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("%s", __FUNCTION__);
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == nat) {
1643762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("%s: out of memory!", __FUNCTION__);
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
16828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_mutex_init(&(nat->thread_mutex), NULL);
16928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(object, field_mNativeData, (jint)nat);
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusError err;
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_error_init(&err);
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_threads_init_default();
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_error_is_set(&err)) {
1783762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("%s: Could not get onto the system bus!", __FUNCTION__);
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dbus_error_free(&err);
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1819e0a19515b9047a00a6e98ce7f20690dff511f43Nick Pelly        dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void cleanupNativeDataNative(JNIEnv* env, jobject object) {
18771f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("%s", __FUNCTION__);
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat =
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (native_data_t *)env->GetIntField(object, field_mNativeData);
19128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
19228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_mutex_destroy(&(nat->thread_mutex));
19328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat) {
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        free(nat);
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg,
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      void *data);
203d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar GaneshDBusHandlerResult agent_event_filter(DBusConnection *conn,
204d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     DBusMessage *msg,
205d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     void *data);
206d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic int register_agent(native_data_t *nat,
207d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                          const char *agent_path, const char *capabilities);
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const DBusObjectPathVTable agent_vtable = {
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    NULL, agent_event_filter, NULL, NULL, NULL, NULL
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2134a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pellystatic unsigned int unix_events_to_dbus_flags(short events) {
2144a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly    return (events & DBUS_WATCH_READABLE ? POLLIN : 0) |
2154a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly           (events & DBUS_WATCH_WRITABLE ? POLLOUT : 0) |
2164a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly           (events & DBUS_WATCH_ERROR ? POLLERR : 0) |
2174a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly           (events & DBUS_WATCH_HANGUP ? POLLHUP : 0);
2184a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly}
2194a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly
2204a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pellystatic short dbus_flags_to_unix_events(unsigned int flags) {
2214a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly    return (flags & POLLIN ? DBUS_WATCH_READABLE : 0) |
2224a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly           (flags & POLLOUT ? DBUS_WATCH_WRITABLE : 0) |
2234a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly           (flags & POLLERR ? DBUS_WATCH_ERROR : 0) |
2244a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly           (flags & POLLHUP ? DBUS_WATCH_HANGUP : 0);
2254a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly}
22628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
22728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic jboolean setUpEventLoop(native_data_t *nat) {
22871f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("%s", __FUNCTION__);
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat != NULL && nat->conn != NULL) {
231d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_threads_init_default();
232d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusError err;
233d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_error_init(&err);
234d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
2355ec09727f44d7f284031e0cad2c96c21b2a8399ehyungseoung.yoo        const char *agent_path = "/android/bluetooth/agent";
2365ec09727f44d7f284031e0cad2c96c21b2a8399ehyungseoung.yoo        const char *capabilities = "DisplayYesNo";
2375ec09727f44d7f284031e0cad2c96c21b2a8399ehyungseoung.yoo        if (register_agent(nat, agent_path, capabilities) < 0) {
2385ec09727f44d7f284031e0cad2c96c21b2a8399ehyungseoung.yoo            dbus_connection_unregister_object_path (nat->conn, agent_path);
2395ec09727f44d7f284031e0cad2c96c21b2a8399ehyungseoung.yoo            return JNI_FALSE;
2405ec09727f44d7f284031e0cad2c96c21b2a8399ehyungseoung.yoo        }
2415ec09727f44d7f284031e0cad2c96c21b2a8399ehyungseoung.yoo
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Add a filter for all incoming messages
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!dbus_connection_add_filter(nat->conn, event_filter, nat, NULL)){
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return JNI_FALSE;
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Set which messages will be processed by this dbus connection
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_bus_add_match(nat->conn,
249c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project                "type='signal',interface='org.freedesktop.DBus'",
250c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project                &err);
251c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        if (dbus_error_is_set(&err)) {
252c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
253c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            return JNI_FALSE;
254c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        }
255c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        dbus_bus_add_match(nat->conn,
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Adapter'",
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                &err);
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_error_is_set(&err)) {
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return JNI_FALSE;
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_bus_add_match(nat->conn,
263d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Device'",
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                &err);
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_error_is_set(&err)) {
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return JNI_FALSE;
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_bus_add_match(nat->conn,
27056d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Input'",
27156d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh                &err);
27256d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh        if (dbus_error_is_set(&err)) {
27356d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
27456d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh            return JNI_FALSE;
27556d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh        }
27656d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh        dbus_bus_add_match(nat->conn,
27756d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Network'",
27856d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh                &err);
27956d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh        if (dbus_error_is_set(&err)) {
28056d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
28156d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh            return JNI_FALSE;
28256d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh        }
28356d26139659c2414d289194c63860ff27ab80da0Jaikumar Ganesh        dbus_bus_add_match(nat->conn,
284c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".NetworkServer'",
285c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                &err);
286c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        if (dbus_error_is_set(&err)) {
287c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
288c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh            return JNI_FALSE;
289c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        }
2902ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh
2912ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh        dbus_bus_add_match(nat->conn,
2922ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".HealthDevice'",
2932ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                &err);
2942ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh        if (dbus_error_is_set(&err)) {
2952ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
2962ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh            return JNI_FALSE;
2972ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh        }
2982ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh
299c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        dbus_bus_add_match(nat->conn,
300d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                "type='signal',interface='org.bluez.AudioSink'",
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                &err);
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_error_is_set(&err)) {
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return JNI_FALSE;
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
307d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return JNI_TRUE;
308d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
309d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return JNI_FALSE;
310d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
312d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
313d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshconst char * get_adapter_path(DBusConnection *conn) {
31432d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    DBusMessage *msg = NULL, *reply = NULL;
315d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    DBusError err;
316d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    const char *device_path = NULL;
317176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    int attempt = 0;
318176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh
319176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    for (attempt = 0; attempt < 1000 && reply == NULL; attempt ++) {
320176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        msg = dbus_message_new_method_call("org.bluez", "/",
321176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh              "org.bluez.Manager", "DefaultAdapter");
322176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        if (!msg) {
3233762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("%s: Can't allocate new method call for get_adapter_path!",
324176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                  __FUNCTION__);
325176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh            return NULL;
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
327176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        dbus_message_append_args(msg, DBUS_TYPE_INVALID);
328176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        dbus_error_init(&err);
329176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
330176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh
331176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        if (!reply) {
332176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh            if (dbus_error_is_set(&err)) {
333176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                if (dbus_error_has_name(&err,
334176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                    "org.freedesktop.DBus.Error.ServiceUnknown")) {
335176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                    // bluetoothd is still down, retry
336176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                    LOG_AND_FREE_DBUS_ERROR(&err);
337176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                    usleep(10000);  // 10 ms
338176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                    continue;
339176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                } else {
340176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                    // Some other error we weren't expecting
341176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                    LOG_AND_FREE_DBUS_ERROR(&err);
342176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh                }
343176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh            }
344176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh            goto failed;
345176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        }
346176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    }
347176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    if (attempt == 1000) {
3483762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Time out while trying to get Adapter path, is bluetoothd up ?");
349176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        goto failed;
350d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
351176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh
352d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (!dbus_message_get_args(reply, &err, DBUS_TYPE_OBJECT_PATH,
353d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                               &device_path, DBUS_TYPE_INVALID)
354d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                               || !device_path){
355d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_error_is_set(&err)) {
356d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
358176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        goto failed;
359d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
360176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    dbus_message_unref(msg);
361d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return device_path;
362176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh
363176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganeshfailed:
364176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    dbus_message_unref(msg);
365176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    return NULL;
366d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh}
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
368d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshstatic int register_agent(native_data_t *nat,
369d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                          const char * agent_path, const char * capabilities)
370d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh{
371d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    DBusMessage *msg, *reply;
372d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    DBusError err;
37375d14c33d795621988a1df173d3d69abe0b6c8f4Nicu Pavel    dbus_bool_t oob = TRUE;
374d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
375d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (!dbus_connection_register_object_path(nat->conn, agent_path,
376d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            &agent_vtable, nat)) {
3773762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("%s: Can't register object path %s for agent!",
378d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh              __FUNCTION__, agent_path);
379d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return -1;
380d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
381d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
382d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    nat->adapter = get_adapter_path(nat->conn);
383176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    if (nat->adapter == NULL) {
384176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh        return -1;
385176c3d64a793a41f2a59b19f3964bf02b4e79a06Jaikumar Ganesh    }
386d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    msg = dbus_message_new_method_call("org.bluez", nat->adapter,
387d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh          "org.bluez.Adapter", "RegisterAgent");
388d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (!msg) {
3893762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("%s: Can't allocate new method call for agent!",
390d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh              __FUNCTION__);
391d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return -1;
392d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    }
393d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path,
394d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                             DBUS_TYPE_STRING, &capabilities,
395d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                             DBUS_TYPE_INVALID);
396d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
397d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    dbus_error_init(&err);
398d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
399d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    dbus_message_unref(msg);
400d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
401d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (!reply) {
4023762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("%s: Can't register agent!", __FUNCTION__);
403d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_error_is_set(&err)) {
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
406d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        return -1;
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
409d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    dbus_message_unref(reply);
410d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    dbus_connection_flush(nat->conn);
411d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
412d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    return 0;
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
41528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic void tearDownEventLoop(native_data_t *nat) {
41671f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("%s", __FUNCTION__);
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (nat != NULL && nat->conn != NULL) {
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
419d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessage *msg, *reply;
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusError err;
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_error_init(&err);
422d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        const char * agent_path = "/android/bluetooth/agent";
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
424d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        msg = dbus_message_new_method_call("org.bluez",
425d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                           nat->adapter,
426d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                           "org.bluez.Adapter",
427d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                           "UnregisterAgent");
4289b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh        if (msg != NULL) {
4299b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh            dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path,
4309b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh                                     DBUS_TYPE_INVALID);
4319b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh            reply = dbus_connection_send_with_reply_and_block(nat->conn,
4329b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh                                                              msg, -1, &err);
4339b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh
4349b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh            if (!reply) {
4359b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh                if (dbus_error_is_set(&err)) {
4369b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh                    LOG_AND_FREE_DBUS_ERROR(&err);
4379b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh                    dbus_error_free(&err);
4389b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh                }
4399b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh            } else {
4409b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh                dbus_message_unref(reply);
4419b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh            }
4429b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh            dbus_message_unref(msg);
4439b0fe60b884b5f291c23da0c34be13354b152593Jaikumar Ganesh        } else {
4443762c311729fe9f3af085c14c5c1fb471d994c03Steve Block             ALOGE("%s: Can't create new method call!", __FUNCTION__);
445d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
447d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_connection_flush(nat->conn);
448d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_connection_unregister_object_path(nat->conn, agent_path);
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_bus_remove_match(nat->conn,
451c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".AudioSink'",
452c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                &err);
453c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        if (dbus_error_is_set(&err)) {
454c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
455c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        }
456c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        dbus_bus_remove_match(nat->conn,
457c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Device'",
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                &err);
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_error_is_set(&err)) {
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_bus_remove_match(nat->conn,
463c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Input'",
464c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                &err);
465c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        if (dbus_error_is_set(&err)) {
466c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
467c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        }
468c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        dbus_bus_remove_match(nat->conn,
469c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Network'",
470c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                &err);
471c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        if (dbus_error_is_set(&err)) {
472c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
473c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        }
474c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh        dbus_bus_remove_match(nat->conn,
475c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".NetworkServer'",
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                &err);
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_error_is_set(&err)) {
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_bus_remove_match(nat->conn,
4812ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".HealthDevice'",
4822ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                &err);
4832ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh        if (dbus_error_is_set(&err)) {
4842ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR(&err);
4852ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh        }
4862ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh        dbus_bus_remove_match(nat->conn,
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "type='signal',interface='org.bluez.audio.Manager'",
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                &err);
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_error_is_set(&err)) {
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_bus_remove_match(nat->conn,
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Adapter'",
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                &err);
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_error_is_set(&err)) {
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
498c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        dbus_bus_remove_match(nat->conn,
499c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project                "type='signal',interface='org.freedesktop.DBus'",
500c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project                &err);
501c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        if (dbus_error_is_set(&err)) {
502c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            LOG_AND_FREE_DBUS_ERROR(&err);
503c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        }
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_connection_remove_filter(nat->conn, event_filter, nat);
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
50728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
50828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
50928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
51028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#define EVENT_LOOP_EXIT 1
51128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#define EVENT_LOOP_ADD  2
51228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#define EVENT_LOOP_REMOVE 3
513f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir#define EVENT_LOOP_WAKEUP 4
51428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
51528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltdbus_bool_t dbusAddWatch(DBusWatch *watch, void *data) {
51628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    native_data_t *nat = (native_data_t *)data;
51728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
51828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (dbus_watch_get_enabled(watch)) {
51928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        // note that we can't just send the watch and inspect it later
52028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        // because we may get a removeWatch call before this data is reacted
52128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        // to by our eventloop and remove this watch..  reading the add first
52228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        // and then inspecting the recently deceased watch would be bad.
52328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        char control = EVENT_LOOP_ADD;
52428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        write(nat->controlFdW, &control, sizeof(char));
52528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
52628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        int fd = dbus_watch_get_fd(watch);
52728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        write(nat->controlFdW, &fd, sizeof(int));
52828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
52928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        unsigned int flags = dbus_watch_get_flags(watch);
53028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        write(nat->controlFdW, &flags, sizeof(unsigned int));
53128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
53228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        write(nat->controlFdW, &watch, sizeof(DBusWatch*));
53328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
53428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    return true;
53528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
53628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
53728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltvoid dbusRemoveWatch(DBusWatch *watch, void *data) {
53828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    native_data_t *nat = (native_data_t *)data;
53928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
54028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    char control = EVENT_LOOP_REMOVE;
54128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    write(nat->controlFdW, &control, sizeof(char));
54228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
54328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    int fd = dbus_watch_get_fd(watch);
54428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    write(nat->controlFdW, &fd, sizeof(int));
54528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
54628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    unsigned int flags = dbus_watch_get_flags(watch);
54728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    write(nat->controlFdW, &flags, sizeof(unsigned int));
54828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
54928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
55028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltvoid dbusToggleWatch(DBusWatch *watch, void *data) {
55128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (dbus_watch_get_enabled(watch)) {
55228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        dbusAddWatch(watch, data);
55328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    } else {
55428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        dbusRemoveWatch(watch, data);
55528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
55628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
55728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
558f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojirvoid dbusWakeup(void *data) {
559f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir    native_data_t *nat = (native_data_t *)data;
560f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir
561f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir    char control = EVENT_LOOP_WAKEUP;
562f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir    write(nat->controlFdW, &control, sizeof(char));
563f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir}
564f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir
56528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic void handleWatchAdd(native_data_t *nat) {
56628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    DBusWatch *watch;
56728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    int newFD;
56828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    unsigned int flags;
56928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
57028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    read(nat->controlFdR, &newFD, sizeof(int));
57128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    read(nat->controlFdR, &flags, sizeof(unsigned int));
57228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    read(nat->controlFdR, &watch, sizeof(DBusWatch *));
5734a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly    short events = dbus_flags_to_unix_events(flags);
57428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
57528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    for (int y = 0; y<nat->pollMemberCount; y++) {
57628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        if ((nat->pollData[y].fd == newFD) &&
57728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                (nat->pollData[y].events == events)) {
57871f2cf116aab893e224056c38ab146bd1538dd3eSteve Block            ALOGV("DBusWatch duplicate add");
57928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            return;
58028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        }
58128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
58228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (nat->pollMemberCount == nat->pollDataSize) {
58371f2cf116aab893e224056c38ab146bd1538dd3eSteve Block        ALOGV("Bluetooth EventLoop poll struct growing");
58428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        struct pollfd *temp = (struct pollfd *)malloc(
58528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                sizeof(struct pollfd) * (nat->pollMemberCount+1));
58628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        if (!temp) {
58728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            return;
58828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        }
58928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        memcpy(temp, nat->pollData, sizeof(struct pollfd) *
59028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                nat->pollMemberCount);
59128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        free(nat->pollData);
59228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->pollData = temp;
59328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        DBusWatch **temp2 = (DBusWatch **)malloc(sizeof(DBusWatch *) *
59428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                (nat->pollMemberCount+1));
59528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        if (!temp2) {
59628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            return;
59728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        }
59828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        memcpy(temp2, nat->watchData, sizeof(DBusWatch *) *
59928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                nat->pollMemberCount);
60028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        free(nat->watchData);
60128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->watchData = temp2;
60228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->pollDataSize++;
60328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
60428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->pollData[nat->pollMemberCount].fd = newFD;
60528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->pollData[nat->pollMemberCount].revents = 0;
60628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->pollData[nat->pollMemberCount].events = events;
60728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->watchData[nat->pollMemberCount] = watch;
60828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->pollMemberCount++;
60928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
61028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
61128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic void handleWatchRemove(native_data_t *nat) {
61228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    int removeFD;
61328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    unsigned int flags;
61428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
61528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    read(nat->controlFdR, &removeFD, sizeof(int));
61628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    read(nat->controlFdR, &flags, sizeof(unsigned int));
6174a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly    short events = dbus_flags_to_unix_events(flags);
61828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
61928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    for (int y = 0; y < nat->pollMemberCount; y++) {
62028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        if ((nat->pollData[y].fd == removeFD) &&
62128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                (nat->pollData[y].events == events)) {
62228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            int newCount = --nat->pollMemberCount;
62328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            // copy the last live member over this one
62428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            nat->pollData[y].fd = nat->pollData[newCount].fd;
62528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            nat->pollData[y].events = nat->pollData[newCount].events;
62628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            nat->pollData[y].revents = nat->pollData[newCount].revents;
62728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            nat->watchData[y] = nat->watchData[newCount];
62828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            return;
62928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        }
63028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
6318564c8da817a845353d213acd8636b76f567b234Steve Block    ALOGW("WatchRemove given with unknown watch");
63228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
63328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
63428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic void *eventLoopMain(void *ptr) {
63528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    native_data_t *nat = (native_data_t *)ptr;
63628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    JNIEnv *env;
63728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
63828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    JavaVMAttachArgs args;
63928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    char name[] = "BT EventLoop";
64028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    args.version = nat->envVer;
64128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    args.name = name;
64228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    args.group = NULL;
64328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
64428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->vm->AttachCurrentThread(&env, &args);
64528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
64628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    dbus_connection_set_watch_functions(nat->conn, dbusAddWatch,
64728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            dbusRemoveWatch, dbusToggleWatch, ptr, NULL);
648f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir    dbus_connection_set_wakeup_main_function(nat->conn, dbusWakeup, ptr, NULL);
64928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
650b8aa037602eff1fe5fbc9cce07a6f9bc34d19a3eJaikumar Ganesh    nat->running = true;
651b8aa037602eff1fe5fbc9cce07a6f9bc34d19a3eJaikumar Ganesh
65228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    while (1) {
65328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        for (int i = 0; i < nat->pollMemberCount; i++) {
65428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            if (!nat->pollData[i].revents) {
65528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                continue;
65628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            }
65728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            if (nat->pollData[i].fd == nat->controlFdR) {
65828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                char data;
65928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                while (recv(nat->controlFdR, &data, sizeof(char), MSG_DONTWAIT)
66028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        != -1) {
66128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    switch (data) {
66228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    case EVENT_LOOP_EXIT:
66328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    {
66428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        dbus_connection_set_watch_functions(nat->conn,
66528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                                NULL, NULL, NULL, NULL, NULL);
66628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        tearDownEventLoop(nat);
66728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        nat->vm->DetachCurrentThread();
668ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson
669ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson                        int fd = nat->controlFdR;
670ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson                        nat->controlFdR = 0;
671ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson                        close(fd);
67228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        return NULL;
67328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    }
67428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    case EVENT_LOOP_ADD:
67528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    {
67628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        handleWatchAdd(nat);
67728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        break;
67828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    }
67928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    case EVENT_LOOP_REMOVE:
68028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    {
68128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        handleWatchRemove(nat);
68228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                        break;
68328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    }
684f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir                    case EVENT_LOOP_WAKEUP:
685f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir                    {
686f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir                        // noop
687f4c6404f50b8a2da601f97bfcd86ab744589b28eAlbert Mojir                        break;
68828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    }
68928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                    }
69028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                }
69128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            } else {
6924a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly                short events = nat->pollData[i].revents;
6934a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly                unsigned int flags = unix_events_to_dbus_flags(events);
6944a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly                dbus_watch_handle(nat->watchData[i], flags);
6954a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly                nat->pollData[i].revents = 0;
6964a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly                // can only do one - it may have caused a 'remove'
6974a364130fb072bf44367e537f8d24e7e00c6ca69Nick Pelly                break;
69828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            }
69928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        }
700b8aa037602eff1fe5fbc9cce07a6f9bc34d19a3eJaikumar Ganesh        while (dbus_connection_dispatch(nat->conn) ==
70128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt                DBUS_DISPATCH_DATA_REMAINS) {
70228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        }
70328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
70428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        poll(nat->pollData, nat->pollMemberCount, -1);
70528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
70628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
70728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#endif // HAVE_BLUETOOTH
70828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
70928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic jboolean startEventLoopNative(JNIEnv *env, jobject object) {
71028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    jboolean result = JNI_FALSE;
71128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#ifdef HAVE_BLUETOOTH
71228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    event_loop_native_data_t *nat = get_native_data(env, object);
71328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
71428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_mutex_lock(&(nat->thread_mutex));
71528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
716b8aa037602eff1fe5fbc9cce07a6f9bc34d19a3eJaikumar Ganesh    nat->running = false;
717b8aa037602eff1fe5fbc9cce07a6f9bc34d19a3eJaikumar Ganesh
71828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (nat->pollData) {
7198564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("trying to start EventLoop a second time!");
72028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        pthread_mutex_unlock( &(nat->thread_mutex) );
72128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        return JNI_FALSE;
72228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
72328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
7248d25cb8a640cfe22809bc6afa493a48adc49c4adIliyan Malchev    nat->pollData = (struct pollfd *)calloc(
7258d25cb8a640cfe22809bc6afa493a48adc49c4adIliyan Malchev            DEFAULT_INITIAL_POLLFD_COUNT, sizeof(struct pollfd));
72628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (!nat->pollData) {
7273762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("out of memory error starting EventLoop!");
72828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        goto done;
72928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
73028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
7318d25cb8a640cfe22809bc6afa493a48adc49c4adIliyan Malchev    nat->watchData = (DBusWatch **)calloc(
7328d25cb8a640cfe22809bc6afa493a48adc49c4adIliyan Malchev            DEFAULT_INITIAL_POLLFD_COUNT, sizeof(DBusWatch *));
73328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (!nat->watchData) {
7343762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("out of memory error starting EventLoop!");
73528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        goto done;
73628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
73728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
73828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->pollDataSize = DEFAULT_INITIAL_POLLFD_COUNT;
73928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->pollMemberCount = 1;
74028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
74128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (socketpair(AF_LOCAL, SOCK_STREAM, 0, &(nat->controlFdR))) {
7423762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Error getting BT control socket");
74328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        goto done;
74428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
74528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->pollData[0].fd = nat->controlFdR;
74628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->pollData[0].events = POLLIN;
74728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
74828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    env->GetJavaVM( &(nat->vm) );
74928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->envVer = env->GetVersion();
75028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
75128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->me = env->NewGlobalRef(object);
75228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
75328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (setUpEventLoop(nat) != JNI_TRUE) {
7543762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("failure setting up Event Loop!");
75528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        goto done;
75628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
75728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
75828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_create(&(nat->thread), NULL, eventLoopMain, nat);
75928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    result = JNI_TRUE;
76028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
76128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltdone:
76228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (JNI_FALSE == result) {
763ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson        if (nat->controlFdW) {
764ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson            close(nat->controlFdW);
76528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            nat->controlFdW = 0;
766ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson        }
767ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson        if (nat->controlFdR) {
768ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson            close(nat->controlFdR);
76928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt            nat->controlFdR = 0;
77028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        }
77128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        if (nat->me) env->DeleteGlobalRef(nat->me);
77228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->me = NULL;
77328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        if (nat->pollData) free(nat->pollData);
77428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->pollData = NULL;
77528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        if (nat->watchData) free(nat->watchData);
77628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->watchData = NULL;
77728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->pollDataSize = 0;
77828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->pollMemberCount = 0;
77928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
78028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
78128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_mutex_unlock(&(nat->thread_mutex));
78228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#endif // HAVE_BLUETOOTH
78328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    return result;
78428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
78528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
78628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic void stopEventLoopNative(JNIEnv *env, jobject object) {
78728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#ifdef HAVE_BLUETOOTH
78828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    native_data_t *nat = get_native_data(env, object);
78928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
79028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_mutex_lock(&(nat->thread_mutex));
79128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    if (nat->pollData) {
79228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        char data = EVENT_LOOP_EXIT;
79328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        ssize_t t = write(nat->controlFdW, &data, sizeof(char));
79428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        void *ret;
79528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        pthread_join(nat->thread, &ret);
79628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
79728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        env->DeleteGlobalRef(nat->me);
79828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->me = NULL;
79928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        free(nat->pollData);
80028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->pollData = NULL;
80128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        free(nat->watchData);
80228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->watchData = NULL;
80328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->pollDataSize = 0;
80428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->pollMemberCount = 0;
805ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson
806ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson        int fd = nat->controlFdW;
80728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        nat->controlFdW = 0;
808ed0d1ab2864a62793ec9c0797251e11cec7e850cJohannes Carlsson        close(fd);
80928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
810b8aa037602eff1fe5fbc9cce07a6f9bc34d19a3eJaikumar Ganesh    nat->running = false;
81128d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_mutex_unlock(&(nat->thread_mutex));
81228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#endif // HAVE_BLUETOOTH
81328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt}
81428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
81528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwaltstatic jboolean isEventLoopRunningNative(JNIEnv *env, jobject object) {
81628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    jboolean result = JNI_FALSE;
81728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#ifdef HAVE_BLUETOOTH
81828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    native_data_t *nat = get_native_data(env, object);
81928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
82028d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_mutex_lock(&(nat->thread_mutex));
821b8aa037602eff1fe5fbc9cce07a6f9bc34d19a3eJaikumar Ganesh    if (nat->running) {
82228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt        result = JNI_TRUE;
82328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    }
82428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    pthread_mutex_unlock(&(nat->thread_mutex));
82528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
82628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt#endif // HAVE_BLUETOOTH
82728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    return result;
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern DBusHandlerResult a2dp_event_filter(DBusMessage *msg, JNIEnv *env);
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Called by dbus during WaitForAndDispatchEventNative()
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg,
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      void *data) {
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    native_data_t *nat;
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JNIEnv *env;
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusError err;
8396d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    DBusHandlerResult ret;
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_error_init(&err);
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nat = (native_data_t *)data;
84428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->vm->GetEnv((void**)&env, nat->envVer);
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL) {
84671f2cf116aab893e224056c38ab146bd1538dd3eSteve Block        ALOGV("%s: not interested (not a signal).", __FUNCTION__);
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
85071f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("%s: Received signal %s:%s from %s", __FUNCTION__,
851d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_get_interface(msg), dbus_message_get_member(msg),
852d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_get_path(msg));
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8546d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    env->PushLocalFrame(EVENT_LOOP_REFS);
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_message_is_signal(msg,
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               "org.bluez.Adapter",
857d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                               "DeviceFound")) {
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char *c_address;
859d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        DBusMessageIter iter;
860d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        jobjectArray str_array = NULL;
861d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (dbus_message_iter_init(msg, &iter)) {
862d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            dbus_message_iter_get_basic(&iter, &c_address);
863d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (dbus_message_iter_next(&iter))
864d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                str_array =
865d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                    parse_remote_device_properties(env, &iter);
866d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        }
867d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (str_array != NULL) {
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->CallVoidMethod(nat->me,
869d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                method_onDeviceFound,
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                env->NewStringUTF(c_address),
871d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                str_array);
872d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        } else
873d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
8746d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (dbus_message_is_signal(msg,
876d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     "org.bluez.Adapter",
877d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     "DeviceDisappeared")) {
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char *c_address;
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_message_get_args(msg, &err,
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  DBUS_TYPE_STRING, &c_address,
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  DBUS_TYPE_INVALID)) {
88271f2cf116aab893e224056c38ab146bd1538dd3eSteve Block            ALOGV("... address = %s", c_address);
883d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            env->CallVoidMethod(nat->me, method_onDeviceDisappeared,
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                env->NewStringUTF(c_address));
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
8866d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (dbus_message_is_signal(msg,
888d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     "org.bluez.Adapter",
889d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     "DeviceCreated")) {
890d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        char *c_object_path;
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_message_get_args(msg, &err,
892d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                  DBUS_TYPE_OBJECT_PATH, &c_object_path,
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  DBUS_TYPE_INVALID)) {
89471f2cf116aab893e224056c38ab146bd1538dd3eSteve Block            ALOGV("... address = %s", c_object_path);
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->CallVoidMethod(nat->me,
896d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                method_onDeviceCreated,
897d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                env->NewStringUTF(c_object_path));
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
8996d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (dbus_message_is_signal(msg,
901d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     "org.bluez.Adapter",
902d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     "DeviceRemoved")) {
903d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        char *c_object_path;
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dbus_message_get_args(msg, &err,
905d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                 DBUS_TYPE_OBJECT_PATH, &c_object_path,
906d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                 DBUS_TYPE_INVALID)) {
90771f2cf116aab893e224056c38ab146bd1538dd3eSteve Block           ALOGV("... Object Path = %s", c_object_path);
908d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh           env->CallVoidMethod(nat->me,
909d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                               method_onDeviceRemoved,
910d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                               env->NewStringUTF(c_object_path));
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
9126d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (dbus_message_is_signal(msg,
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      "org.bluez.Adapter",
915d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                      "PropertyChanged")) {
916d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        jobjectArray str_array = parse_adapter_property_change(env, msg);
917d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (str_array != NULL) {
918d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            /* Check if bluetoothd has (re)started, if so update the path. */
919d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            jstring property =(jstring) env->GetObjectArrayElement(str_array, 0);
920d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            const char *c_property = env->GetStringUTFChars(property, NULL);
921d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            if (!strncmp(c_property, "Powered", strlen("Powered"))) {
922d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                jstring value =
923d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                    (jstring) env->GetObjectArrayElement(str_array, 1);
924d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                const char *c_value = env->GetStringUTFChars(value, NULL);
925d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                if (!strncmp(c_value, "true", strlen("true")))
926d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                    nat->adapter = get_adapter_path(nat->conn);
927d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                env->ReleaseStringUTFChars(value, c_value);
928d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            }
929d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            env->ReleaseStringUTFChars(property, c_property);
930d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->CallVoidMethod(nat->me,
932d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                              method_onPropertyChanged,
933d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                              str_array);
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
9356d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (dbus_message_is_signal(msg,
937d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                      "org.bluez.Device",
938d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                      "PropertyChanged")) {
939d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        jobjectArray str_array = parse_remote_device_property_change(env, msg);
940d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        if (str_array != NULL) {
941d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            const char *remote_device_path = dbus_message_get_path(msg);
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->CallVoidMethod(nat->me,
943d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                            method_onDevicePropertyChanged,
944d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                            env->NewStringUTF(remote_device_path),
945d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                            str_array);
946c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
9476d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
9485e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh    } else if (dbus_message_is_signal(msg,
9495e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh                                      "org.bluez.Device",
9505e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh                                      "DisconnectRequested")) {
9515e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh        const char *remote_device_path = dbus_message_get_path(msg);
9525e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh        env->CallVoidMethod(nat->me,
9535e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh                            method_onDeviceDisconnectRequested,
9545e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh                            env->NewStringUTF(remote_device_path));
9555e59ca8ae4e29efb77acbd5513dcc109ea5dd2b4Jaikumar Ganesh        goto success;
956545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh    } else if (dbus_message_is_signal(msg,
957545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh                                      "org.bluez.Input",
958545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh                                      "PropertyChanged")) {
959545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh
960545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh        jobjectArray str_array =
961545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh                    parse_input_property_change(env, msg);
962545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh        if (str_array != NULL) {
963545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh            const char *c_path = dbus_message_get_path(msg);
964545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh            env->CallVoidMethod(nat->me,
965545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh                                method_onInputDevicePropertyChanged,
966545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh                                env->NewStringUTF(c_path),
967545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh                                str_array);
968545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh        } else {
969545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
970545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh        }
971545e6708adda6859932b55fd824794b1401f5318Jaikumar Ganesh        goto success;
9726fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    } else if (dbus_message_is_signal(msg,
9736fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                                     "org.bluez.Network",
9746fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                                     "PropertyChanged")) {
9756fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang
9766fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang       jobjectArray str_array =
9776fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                   parse_pan_property_change(env, msg);
9786fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang       if (str_array != NULL) {
9796fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang           const char *c_path = dbus_message_get_path(msg);
9806fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang           env->CallVoidMethod(nat->me,
9816fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                               method_onPanDevicePropertyChanged,
9826fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                               env->NewStringUTF(c_path),
9836fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                               str_array);
9846fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang       } else {
9856fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
9866fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang       }
9876fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang       goto success;
988c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh    } else if (dbus_message_is_signal(msg,
989c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                     "org.bluez.NetworkServer",
990c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                     "DeviceDisconnected")) {
991c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       char *c_address;
992c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       if (dbus_message_get_args(msg, &err,
993c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                  DBUS_TYPE_STRING, &c_address,
994c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                  DBUS_TYPE_INVALID)) {
995c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh           env->CallVoidMethod(nat->me,
996c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                               method_onNetworkDeviceDisconnected,
997c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                               env->NewStringUTF(c_address));
998c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       } else {
999c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
1000c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       }
1001c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       goto success;
1002c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh    } else if (dbus_message_is_signal(msg,
1003c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                     "org.bluez.NetworkServer",
1004c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                     "DeviceConnected")) {
1005c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       char *c_address;
1006707952ecd4b6cae25aabcf51f94d702a65847e9eJaikumar Ganesh       char *c_iface;
1007c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       uint16_t uuid;
1008c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh
1009c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       if (dbus_message_get_args(msg, &err,
1010c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                  DBUS_TYPE_STRING, &c_address,
1011707952ecd4b6cae25aabcf51f94d702a65847e9eJaikumar Ganesh                                  DBUS_TYPE_STRING, &c_iface,
1012c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                  DBUS_TYPE_UINT16, &uuid,
1013c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                                  DBUS_TYPE_INVALID)) {
1014c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh           env->CallVoidMethod(nat->me,
1015c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                               method_onNetworkDeviceConnected,
1016c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                               env->NewStringUTF(c_address),
1017707952ecd4b6cae25aabcf51f94d702a65847e9eJaikumar Ganesh                               env->NewStringUTF(c_iface),
1018c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh                               uuid);
1019c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       } else {
1020c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
1021c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       }
1022c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh       goto success;
10232ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh    } else if (dbus_message_is_signal(msg,
10242ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                     "org.bluez.HealthDevice",
10252ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                     "ChannelConnected")) {
10262ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       const char *c_path = dbus_message_get_path(msg);
10272ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       const char *c_channel_path;
10282ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       jboolean exists = JNI_TRUE;
10292ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       if (dbus_message_get_args(msg, &err,
10302ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                  DBUS_TYPE_OBJECT_PATH, &c_channel_path,
10312ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                  DBUS_TYPE_INVALID)) {
10322ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh           env->CallVoidMethod(nat->me,
10332ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                               method_onHealthDeviceChannelChanged,
10342ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                               env->NewStringUTF(c_path),
10352ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                               env->NewStringUTF(c_channel_path),
10362ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                               exists);
10372ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       } else {
10382ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
10392ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       }
10402ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       goto success;
10412ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh    } else if (dbus_message_is_signal(msg,
1042ae37d06dd0f844fe397b76210e6d145abf4210b6Jaikumar Ganesh                                     "org.bluez.HealthDevice",
10432ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                     "ChannelDeleted")) {
10442ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh
10452ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       const char *c_path = dbus_message_get_path(msg);
10462ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       const char *c_channel_path;
10472ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       jboolean exists = JNI_FALSE;
10482ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       if (dbus_message_get_args(msg, &err,
10492ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                  DBUS_TYPE_OBJECT_PATH, &c_channel_path,
10502ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                  DBUS_TYPE_INVALID)) {
10512ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh           env->CallVoidMethod(nat->me,
10522ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                               method_onHealthDeviceChannelChanged,
10532ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                               env->NewStringUTF(c_path),
10542ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                               env->NewStringUTF(c_channel_path),
10552ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                               exists);
10562ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       } else {
10572ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
10582ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       }
10592ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       goto success;
10602ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh    } else if (dbus_message_is_signal(msg,
10612ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                     "org.bluez.HealthDevice",
10622ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                     "PropertyChanged")) {
10632ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh        jobjectArray str_array =
10642ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                    parse_health_device_property_change(env, msg);
10652ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh        if (str_array != NULL) {
10662ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh            const char *c_path = dbus_message_get_path(msg);
10672ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh            env->CallVoidMethod(nat->me,
10682ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                method_onHealthDevicePropertyChanged,
10692ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                env->NewStringUTF(c_path),
10702ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh                                str_array);
10712ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       } else {
10722ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
10732ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       }
10742ea1e85dcb57d17f5782dbafa1d25eb51c630e4bJaikumar Ganesh       goto success;
1075c1520ecb41600cd364f03c4c100f927a98924e6aJaikumar Ganesh    }
10766d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
10776d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    ret = a2dp_event_filter(msg, env);
10786d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    env->PopLocalFrame(NULL);
10796d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    return ret;
10806d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
10816d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganeshsuccess:
10826d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    env->PopLocalFrame(NULL);
10836d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    return DBUS_HANDLER_RESULT_HANDLED;
10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Called by dbus during WaitForAndDispatchEventNative()
1087d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar GaneshDBusHandlerResult agent_event_filter(DBusConnection *conn,
1088d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                     DBusMessage *msg, void *data) {
108928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    native_data_t *nat = (native_data_t *)data;
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    JNIEnv *env;
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_METHOD_CALL) {
109271f2cf116aab893e224056c38ab146bd1538dd3eSteve Block        ALOGV("%s: not interested (not a method call).", __FUNCTION__);
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10956215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block    ALOGI("%s: Received method %s:%s", __FUNCTION__,
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         dbus_message_get_interface(msg), dbus_message_get_member(msg));
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1098d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (nat == NULL) return DBUS_HANDLER_RESULT_HANDLED;
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1100d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    nat->vm->GetEnv((void**)&env, nat->envVer);
11016d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    env->PushLocalFrame(EVENT_LOOP_REFS);
11026d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
1103d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh    if (dbus_message_is_method_call(msg,
1104d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            "org.bluez.Agent", "Cancel")) {
1105d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->CallVoidMethod(nat->me, method_onAgentCancel);
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // reply
11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply = dbus_message_new_method_return(msg);
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!reply) {
11093762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("%s: Cannot create message reply\n", __FUNCTION__);
11106d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh            goto failure;
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_connection_send(nat->conn, reply, NULL);
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_unref(reply);
11146d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (dbus_message_is_method_call(msg,
1117d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            "org.bluez.Agent", "Authorize")) {
1118d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        char *object_path;
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char *uuid;
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!dbus_message_get_args(msg, NULL,
1121d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_TYPE_OBJECT_PATH, &object_path,
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                   DBUS_TYPE_STRING, &uuid,
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                   DBUS_TYPE_INVALID)) {
11243762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("%s: Invalid arguments for Authorize() method", __FUNCTION__);
11256d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh            goto failure;
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
112871f2cf116aab893e224056c38ab146bd1538dd3eSteve Block        ALOGV("... object_path = %s", object_path);
112971f2cf116aab893e224056c38ab146bd1538dd3eSteve Block        ALOGV("... uuid = %s", uuid);
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1131a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie        dbus_message_ref(msg);  // increment refcount because we pass to java
113214fcf900ce65e5c8c952c95ee12041f8de16fbb7Jeff Brown        env->CallVoidMethod(nat->me, method_onAgentAuthorize,
1133a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie                env->NewStringUTF(object_path), env->NewStringUTF(uuid),
1134a0c680393f2dd03a937c598b2cb9abf98a58152cMatthew Xie                int(msg));
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11366d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (dbus_message_is_method_call(msg,
1138cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            "org.bluez.Agent", "OutOfBandAvailable")) {
1139cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        char *object_path;
1140cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        if (!dbus_message_get_args(msg, NULL,
1141cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                                   DBUS_TYPE_OBJECT_PATH, &object_path,
1142cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                                   DBUS_TYPE_INVALID)) {
11433762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("%s: Invalid arguments for OutOfBandData available() method", __FUNCTION__);
1144cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            goto failure;
1145cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        }
1146cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh
114771f2cf116aab893e224056c38ab146bd1538dd3eSteve Block        ALOGV("... object_path = %s", object_path);
1148cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh
1149cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        bool available =
1150cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            env->CallBooleanMethod(nat->me, method_onAgentOutOfBandDataAvailable,
1151cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                env->NewStringUTF(object_path));
1152cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh
1153cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh
1154cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        // reply
1155cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        if (available) {
1156cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            DBusMessage *reply = dbus_message_new_method_return(msg);
1157cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            if (!reply) {
11583762c311729fe9f3af085c14c5c1fb471d994c03Steve Block                ALOGE("%s: Cannot create message reply\n", __FUNCTION__);
1159cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                goto failure;
1160cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            }
1161cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            dbus_connection_send(nat->conn, reply, NULL);
1162cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            dbus_message_unref(reply);
1163cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        } else {
1164cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            DBusMessage *reply = dbus_message_new_error(msg,
1165cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                    "org.bluez.Error.DoesNotExist", "OutofBand data not available");
1166cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            if (!reply) {
11673762c311729fe9f3af085c14c5c1fb471d994c03Steve Block                ALOGE("%s: Cannot create message reply\n", __FUNCTION__);
1168cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                goto failure;
1169cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            }
1170cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            dbus_connection_send(nat->conn, reply, NULL);
1171cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            dbus_message_unref(reply);
1172cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        }
1173cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        goto success;
1174cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh    } else if (dbus_message_is_method_call(msg,
1175d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh            "org.bluez.Agent", "RequestPinCode")) {
1176d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        char *object_path;
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!dbus_message_get_args(msg, NULL,
1178d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                   DBUS_TYPE_OBJECT_PATH, &object_path,
11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                   DBUS_TYPE_INVALID)) {
11803762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("%s: Invalid arguments for RequestPinCode() method", __FUNCTION__);
11816d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh            goto failure;
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1184d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        dbus_message_ref(msg);  // increment refcount because we pass to java
1185d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh        env->CallVoidMethod(nat->me, method_onRequestPinCode,
1186d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                       env->NewStringUTF(object_path),
1187d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                                       int(msg));
11886d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (dbus_message_is_method_call(msg,
1190b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            "org.bluez.Agent", "RequestPasskey")) {
1191b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        char *object_path;
1192b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        if (!dbus_message_get_args(msg, NULL,
1193b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                   DBUS_TYPE_OBJECT_PATH, &object_path,
1194b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                   DBUS_TYPE_INVALID)) {
11953762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("%s: Invalid arguments for RequestPasskey() method", __FUNCTION__);
11966d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh            goto failure;
1197b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        }
1198b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
1199b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_ref(msg);  // increment refcount because we pass to java
1200b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        env->CallVoidMethod(nat->me, method_onRequestPasskey,
1201b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                       env->NewStringUTF(object_path),
1202b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                       int(msg));
12036d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
1204b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    } else if (dbus_message_is_method_call(msg,
1205cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            "org.bluez.Agent", "RequestOobData")) {
1206cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        char *object_path;
1207cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        if (!dbus_message_get_args(msg, NULL,
1208cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                                   DBUS_TYPE_OBJECT_PATH, &object_path,
1209cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                                   DBUS_TYPE_INVALID)) {
12103762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("%s: Invalid arguments for RequestOobData() method", __FUNCTION__);
1211cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh            goto failure;
1212cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        }
1213cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh
1214cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        dbus_message_ref(msg);  // increment refcount because we pass to java
1215cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        env->CallVoidMethod(nat->me, method_onRequestOobData,
1216cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                                       env->NewStringUTF(object_path),
1217cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh                                       int(msg));
1218cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh        goto success;
1219cc5494c9996f809e36539b24e8b6b67683383d29Jaikumar Ganesh    } else if (dbus_message_is_method_call(msg,
122032d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh            "org.bluez.Agent", "DisplayPasskey")) {
122132d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        char *object_path;
122232d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        uint32_t passkey;
122332d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        if (!dbus_message_get_args(msg, NULL,
122432d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                   DBUS_TYPE_OBJECT_PATH, &object_path,
122532d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                   DBUS_TYPE_UINT32, &passkey,
122632d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                   DBUS_TYPE_INVALID)) {
12273762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("%s: Invalid arguments for RequestPasskey() method", __FUNCTION__);
122832d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh            goto failure;
122932d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        }
123032d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh
123132d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        dbus_message_ref(msg);  // increment refcount because we pass to java
123232d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        env->CallVoidMethod(nat->me, method_onDisplayPasskey,
123332d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                       env->NewStringUTF(object_path),
123432d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                       passkey,
123532d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                       int(msg));
123632d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        goto success;
123732d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    } else if (dbus_message_is_method_call(msg,
1238b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh            "org.bluez.Agent", "RequestConfirmation")) {
1239b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        char *object_path;
1240b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        uint32_t passkey;
1241b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        if (!dbus_message_get_args(msg, NULL,
1242b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                   DBUS_TYPE_OBJECT_PATH, &object_path,
1243b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                   DBUS_TYPE_UINT32, &passkey,
1244b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                   DBUS_TYPE_INVALID)) {
12453762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("%s: Invalid arguments for RequestConfirmation() method", __FUNCTION__);
12466d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh            goto failure;
1247b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        }
1248b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
1249b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        dbus_message_ref(msg);  // increment refcount because we pass to java
125032d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        env->CallVoidMethod(nat->me, method_onRequestPasskeyConfirmation,
1251b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                       env->NewStringUTF(object_path),
1252b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                       passkey,
1253b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh                                       int(msg));
12546d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
1255b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    } else if (dbus_message_is_method_call(msg,
125632d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh            "org.bluez.Agent", "RequestPairingConsent")) {
125732d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        char *object_path;
125832d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        if (!dbus_message_get_args(msg, NULL,
125932d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                   DBUS_TYPE_OBJECT_PATH, &object_path,
126032d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                   DBUS_TYPE_INVALID)) {
12613762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("%s: Invalid arguments for RequestPairingConsent() method", __FUNCTION__);
126232d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh            goto failure;
126332d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        }
126432d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh
126532d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        dbus_message_ref(msg);  // increment refcount because we pass to java
126632d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        env->CallVoidMethod(nat->me, method_onRequestPairingConsent,
126732d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                       env->NewStringUTF(object_path),
126832d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh                                       int(msg));
126932d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        goto success;
127032d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    } else if (dbus_message_is_method_call(msg,
1271d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                  "org.bluez.Agent", "Release")) {
12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // reply
12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DBusMessage *reply = dbus_message_new_method_return(msg);
12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!reply) {
12753762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("%s: Cannot create message reply\n", __FUNCTION__);
12766d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh            goto failure;
12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_connection_send(nat->conn, reply, NULL);
12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_message_unref(reply);
12806d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh        goto success;
12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
128271f2cf116aab893e224056c38ab146bd1538dd3eSteve Block        ALOGV("%s:%s is ignored", dbus_message_get_interface(msg), dbus_message_get_member(msg));
12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12856d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganeshfailure:
12866d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    env->PopLocalFrame(NULL);
12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
12886d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
12896d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganeshsuccess:
12906d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    env->PopLocalFrame(NULL);
12916d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh    return DBUS_HANDLER_RESULT_HANDLED;
12926d56b530e189d7213ec77d43d3d8af97fee04179Jaikumar Ganesh
12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_BLUETOOTH
129828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
1299d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshvoid onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) {
130071f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("%s", __FUNCTION__);
13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
130228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    native_data_t *nat = (native_data_t *)n;
13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char *address = (const char *)user;
13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusError err;
13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_error_init(&err);
130628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    JNIEnv *env;
1307a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    jstring addr;
1308a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh
130928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->vm->GetEnv((void**)&env, nat->envVer);
13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
131171f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("... address = %s", address);
13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint result = BOND_RESULT_SUCCESS;
13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_set_error_from_message(&err, msg)) {
13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationFailed")) {
13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Pins did not match, or remote device did not respond to pin
13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // request in time
131871f2cf116aab893e224056c38ab146bd1538dd3eSteve Block            ALOGV("... error = %s (%s)\n", err.name, err.message);
13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = BOND_RESULT_AUTH_FAILED;
13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationRejected")) {
13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // We rejected pairing, or the remote side rejected pairing. This
13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // happens if either side presses 'cancel' at the pairing dialog.
132371f2cf116aab893e224056c38ab146bd1538dd3eSteve Block            ALOGV("... error = %s (%s)\n", err.name, err.message);
13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = BOND_RESULT_AUTH_REJECTED;
13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationCanceled")) {
13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Not sure if this happens
132771f2cf116aab893e224056c38ab146bd1538dd3eSteve Block            ALOGV("... error = %s (%s)\n", err.name, err.message);
13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = BOND_RESULT_AUTH_CANCELED;
13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.ConnectionAttemptFailed")) {
13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Other device is not responding at all
133171f2cf116aab893e224056c38ab146bd1538dd3eSteve Block            ALOGV("... error = %s (%s)\n", err.name, err.message);
13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = BOND_RESULT_REMOTE_DEVICE_DOWN;
13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AlreadyExists")) {
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // already bonded
133571f2cf116aab893e224056c38ab146bd1538dd3eSteve Block            ALOGV("... error = %s (%s)\n", err.name, err.message);
13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = BOND_RESULT_SUCCESS;
13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.InProgress") &&
13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   !strcmp(err.message, "Bonding in progress")) {
133971f2cf116aab893e224056c38ab146bd1538dd3eSteve Block            ALOGV("... error = %s (%s)\n", err.name, err.message);
13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            goto done;
13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.InProgress") &&
13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   !strcmp(err.message, "Discover in progress")) {
134371f2cf116aab893e224056c38ab146bd1538dd3eSteve Block            ALOGV("... error = %s (%s)\n", err.name, err.message);
13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = BOND_RESULT_DISCOVERY_IN_PROGRESS;
134532d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.RepeatedAttempts")) {
134671f2cf116aab893e224056c38ab146bd1538dd3eSteve Block            ALOGV("... error = %s (%s)\n", err.name, err.message);
134732d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh            result = BOND_RESULT_REPEATED_ATTEMPTS;
134832d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationTimeout")) {
134971f2cf116aab893e224056c38ab146bd1538dd3eSteve Block            ALOGV("... error = %s (%s)\n", err.name, err.message);
135032d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh            result = BOND_RESULT_AUTH_TIMEOUT;
13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
13523762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = BOND_RESULT_ERROR;
13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1357a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    addr = env->NewStringUTF(address);
135828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    env->CallVoidMethod(nat->me,
1359d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                        method_onCreatePairedDeviceResult,
1360a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh                        addr,
13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        result);
1362a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    env->DeleteLocalRef(addr);
13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdone:
13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_error_free(&err);
13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    free(user);
13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13681caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganeshvoid onCreateDeviceResult(DBusMessage *msg, void *user, void *n) {
136971f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("%s", __FUNCTION__);
13701caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
13711caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    native_data_t *nat = (native_data_t *)n;
13721caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    const char *address= (const char *)user;
13731caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    DBusError err;
13741caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    dbus_error_init(&err);
13751caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    JNIEnv *env;
13761caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    nat->vm->GetEnv((void**)&env, nat->envVer);
13771caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
137871f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("... Address = %s", address);
13791caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
138016fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly    jint result = CREATE_DEVICE_SUCCESS;
13811caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    if (dbus_set_error_from_message(&err, msg)) {
138216fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly        if (dbus_error_has_name(&err, "org.bluez.Error.AlreadyExists")) {
138316fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly            result = CREATE_DEVICE_ALREADY_EXISTS;
1384cf5f6527401bcbd9f558e41a5b067d4d02920dc7Jaikumar Ganesh        } else {
1385cf5f6527401bcbd9f558e41a5b067d4d02920dc7Jaikumar Ganesh            result = CREATE_DEVICE_FAILED;
138616fb88a673c41b93c5d57ccb28c2697e7d87701aNick Pelly        }
13871caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        LOG_AND_FREE_DBUS_ERROR(&err);
13881caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    }
1389a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    jstring addr = env->NewStringUTF(address);
13901caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    env->CallVoidMethod(nat->me,
13911caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                        method_onCreateDeviceResult,
1392a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh                        addr,
13931caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                        result);
1394a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    env->DeleteLocalRef(addr);
13951caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    free(user);
13961caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh}
13971caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
13981caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganeshvoid onDiscoverServicesResult(DBusMessage *msg, void *user, void *n) {
139971f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("%s", __FUNCTION__);
14001caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
14011caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    native_data_t *nat = (native_data_t *)n;
14021caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    const char *path = (const char *)user;
14031caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    DBusError err;
14041caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    dbus_error_init(&err);
14051caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    JNIEnv *env;
14061caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    nat->vm->GetEnv((void**)&env, nat->envVer);
14071caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
140871f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("... Device Path = %s", path);
14091caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
14101caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    bool result = JNI_TRUE;
14111caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    if (dbus_set_error_from_message(&err, msg)) {
14121caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        LOG_AND_FREE_DBUS_ERROR(&err);
14131caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh        result = JNI_FALSE;
14141caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    }
1415a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    jstring jPath = env->NewStringUTF(path);
14161caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    env->CallVoidMethod(nat->me,
14171caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                        method_onDiscoverServicesResult,
1418a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh                        jPath,
14191caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh                        result);
1420a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    env->DeleteLocalRef(jPath);
14211caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh    free(user);
14221caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh}
14231caa6d111eff6814760ec156b14adc29aa3aae6cJaikumar Ganesh
1424d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganeshvoid onGetDeviceServiceChannelResult(DBusMessage *msg, void *user, void *n) {
142571f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("%s", __FUNCTION__);
14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char *address = (const char *) user;
142828d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    native_data_t *nat = (native_data_t *) n;
142928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DBusError err;
14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dbus_error_init(&err);
143228d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    JNIEnv *env;
143328d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    nat->vm->GetEnv((void**)&env, nat->envVer);
143428d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt
14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint channel = -2;
14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
143771f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("... address = %s", address);
14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dbus_set_error_from_message(&err, msg) ||
14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        !dbus_message_get_args(msg, &err,
14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               DBUS_TYPE_INT32, &channel,
14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               DBUS_TYPE_INVALID)) {
14433762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dbus_error_free(&err);
14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdone:
1448a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    jstring addr = env->NewStringUTF(address);
144928d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    env->CallVoidMethod(nat->me,
1450d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh                        method_onGetDeviceServiceChannelResult,
1451a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh                        addr,
14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        channel);
1453a7c0bdc4e46301530c89c67ec3ce6ae8df7260d7Jaikumar Ganesh    env->DeleteLocalRef(addr);
14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    free(user);
14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1456de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh
1457de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganeshvoid onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
145871f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("%s", __FUNCTION__);
1459de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh
1460de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    native_data_t *nat = (native_data_t *)n;
1461de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    const char *path = (const char *)user;
1462de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    DBusError err;
1463de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    dbus_error_init(&err);
1464de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    JNIEnv *env;
1465de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    nat->vm->GetEnv((void**)&env, nat->envVer);
1466de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh
1467fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh    jint result = INPUT_OPERATION_SUCCESS;
1468de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    if (dbus_set_error_from_message(&err, msg)) {
1469fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) {
1470fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            result = INPUT_CONNECT_FAILED_ATTEMPT_FAILED;
1471fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".AlreadyConnected")) {
1472fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            result = INPUT_CONNECT_FAILED_ALREADY_CONNECTED;
1473fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) {
1474fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            // TODO():This is flaky, need to change Bluez to add new error codes
1475fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            if (!strcmp(err.message, "Transport endpoint is not connected")) {
1476fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh              result = INPUT_DISCONNECT_FAILED_NOT_CONNECTED;
1477fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            } else {
1478fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh              result = INPUT_OPERATION_GENERIC_FAILURE;
1479fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            }
1480fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        } else {
1481fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            result = INPUT_OPERATION_GENERIC_FAILURE;
1482fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        }
1483de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh        LOG_AND_FREE_DBUS_ERROR(&err);
1484de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    }
1485fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh
148671f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("... Device Path = %s, result = %d", path, result);
1487de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    jstring jPath = env->NewStringUTF(path);
1488de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    env->CallVoidMethod(nat->me,
1489de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh                        method_onInputDeviceConnectionResult,
1490de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh                        jPath,
1491de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh                        result);
1492de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    env->DeleteLocalRef(jPath);
1493de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh    free(user);
1494de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh}
1495de07503a382e81ba82f4cd4dee81ff2fbf3295bcJaikumar Ganesh
14966fdd0c6274c81b337ad35b70480f881daf7354c3Danica Changvoid onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
149771f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("%s", __FUNCTION__);
14986fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang
14996fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    native_data_t *nat = (native_data_t *)n;
15006fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    const char *path = (const char *)user;
15016fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    DBusError err;
15026fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    dbus_error_init(&err);
15036fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    JNIEnv *env;
15046fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    nat->vm->GetEnv((void**)&env, nat->envVer);
15056fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang
1506fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh    jint result = PAN_OPERATION_SUCCESS;
15076fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    if (dbus_set_error_from_message(&err, msg)) {
1508fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) {
1509fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            result = PAN_CONNECT_FAILED_ATTEMPT_FAILED;
1510fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) {
1511fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            // TODO():This is flaky, need to change Bluez to add new error codes
1512fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            if (!strcmp(err.message, "Device already connected")) {
1513fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh                result = PAN_CONNECT_FAILED_ALREADY_CONNECTED;
1514fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            } else if (!strcmp(err.message, "Device not connected")) {
1515fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh                result = PAN_DISCONNECT_FAILED_NOT_CONNECTED;
1516fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            } else {
1517fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh                result = PAN_OPERATION_GENERIC_FAILURE;
1518fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            }
1519fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        } else {
1520fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh            result = PAN_OPERATION_GENERIC_FAILURE;
1521fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh        }
15226fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang        LOG_AND_FREE_DBUS_ERROR(&err);
15236fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    }
1524fbe807d064ada99211b102914df514aa562256f8Jaikumar Ganesh
152571f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("... Pan Device Path = %s, result = %d", path, result);
15266fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    jstring jPath = env->NewStringUTF(path);
15276fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    env->CallVoidMethod(nat->me,
15286fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                        method_onPanDeviceConnectionResult,
15296fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                        jPath,
15306fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                        result);
15316fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    env->DeleteLocalRef(jPath);
15326fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    free(user);
15336fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang}
15346fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang
1535b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganeshvoid onHealthDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
153671f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("%s", __FUNCTION__);
1537b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh
1538b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    native_data_t *nat = (native_data_t *)n;
1539b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    DBusError err;
1540b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    dbus_error_init(&err);
1541b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    JNIEnv *env;
1542b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    nat->vm->GetEnv((void**)&env, nat->envVer);
1543b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh
1544b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    jint result = HEALTH_OPERATION_SUCCESS;
1545b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    if (dbus_set_error_from_message(&err, msg)) {
1546b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh        if (!strcmp(err.name, BLUEZ_ERROR_IFC ".InvalidArgs")) {
1547b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh            result = HEALTH_OPERATION_INVALID_ARGS;
1548b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".HealthError")) {
1549b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh            result = HEALTH_OPERATION_ERROR;
1550b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotFound")) {
1551b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh            result = HEALTH_OPERATION_NOT_FOUND;
1552b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotAllowed")) {
1553b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh            result = HEALTH_OPERATION_NOT_ALLOWED;
1554b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh        } else {
1555b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh            result = HEALTH_OPERATION_GENERIC_FAILURE;
1556b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh        }
1557b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh        LOG_AND_FREE_DBUS_ERROR(&err);
1558b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    }
1559b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh
1560b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    jint code = *(int *) user;
156171f2cf116aab893e224056c38ab146bd1538dd3eSteve Block    ALOGV("... Health Device Code = %d, result = %d", code, result);
1562b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    env->CallVoidMethod(nat->me,
1563b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh                        method_onHealthDeviceConnectionResult,
1564b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh                        code,
1565b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh                        result);
1566b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh    free(user);
1567b5d2d4526cd2c0117b7a33b1297ac683c37ac5c7Jaikumar Ganesh}
15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod sMethods[] = {
15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     /* name, signature, funcPtr */
15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"classInitNative", "()V", (void *)classInitNative},
15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative},
15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
157528d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    {"startEventLoopNative", "()V", (void *)startEventLoopNative},
157628d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    {"stopEventLoopNative", "()V", (void *)stopEventLoopNative},
157728d139fa953c0b3bf2c66d92587e5287ec4dd5abRobert Greenwalt    {"isEventLoopRunningNative", "()Z", (void *)isEventLoopRunningNative}
15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_server_BluetoothEventLoop(JNIEnv *env) {
15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return AndroidRuntime::registerNativeMethods(env,
15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            "android/server/BluetoothEventLoop", sMethods, NELEM(sMethods));
15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} /* namespace android */
1586