1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define DBUS_CLASS_NAME BLUEZ_DBUS_BASE_IFC ".Database" 18#define LOG_TAG "bluetooth_Database.cpp" 19 20#include "android_bluetooth_common.h" 21#include "android_runtime/AndroidRuntime.h" 22#include "JNIHelp.h" 23#include "jni.h" 24#include "utils/Log.h" 25 26#ifdef HAVE_BLUETOOTH 27#include <dbus/dbus.h> 28#endif 29 30namespace android { 31 32#ifdef HAVE_BLUETOOTH 33static DBusConnection* conn = NULL; // Singleton thread-safe connection 34#endif 35 36static void classInitNative(JNIEnv* env, jclass clazz) { 37 LOGV(__FUNCTION__); 38#ifdef HAVE_BLUETOOTH 39 conn = NULL; 40#endif 41} 42 43static void initializeNativeDataNative(JNIEnv* env, jobject object) { 44 LOGV(__FUNCTION__); 45 46#ifdef HAVE_BLUETOOTH 47 if (conn == NULL) { 48 DBusError err; 49 dbus_error_init(&err); 50 dbus_threads_init_default(); 51 conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); 52 if (dbus_error_is_set(&err)) { 53 LOGE("Could not get onto the system bus!"); 54 dbus_error_free(&err); 55 } 56 dbus_connection_set_exit_on_disconnect(conn, FALSE); 57 } 58#endif 59} 60 61static void cleanupNativeDataNative(JNIEnv* env, jobject object) { 62 LOGV(__FUNCTION__); 63} 64 65static jint addServiceRecordNative(JNIEnv *env, jobject object, 66 jbyteArray record) { 67 LOGV(__FUNCTION__); 68#ifdef HAVE_BLUETOOTH 69 if (conn != NULL) { 70 jbyte* c_record = env->GetByteArrayElements(record, NULL); 71 DBusMessage *reply = dbus_func_args(env, 72 conn, 73 BLUEZ_DBUS_BASE_PATH, 74 DBUS_CLASS_NAME, 75 "AddServiceRecord", 76 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, 77 &c_record, 78 env->GetArrayLength(record), 79 DBUS_TYPE_INVALID); 80 env->ReleaseByteArrayElements(record, c_record, JNI_ABORT); 81 return reply ? dbus_returns_uint32(env, reply) : -1; 82 } 83#endif 84 return -1; 85} 86 87static jint addServiceRecordFromXmlNative(JNIEnv *env, jobject object, 88 jstring record) { 89 LOGV(__FUNCTION__); 90#ifdef HAVE_BLUETOOTH 91 if (conn != NULL) { 92 const char *c_record = env->GetStringUTFChars(record, NULL); 93 DBusMessage *reply = dbus_func_args(env, 94 conn, 95 BLUEZ_DBUS_BASE_PATH, 96 DBUS_CLASS_NAME, 97 "AddServiceRecordFromXML", 98 DBUS_TYPE_STRING, &c_record, 99 DBUS_TYPE_INVALID); 100 env->ReleaseStringUTFChars(record, c_record); 101 return reply ? dbus_returns_uint32(env, reply) : -1; 102 } 103#endif 104 return -1; 105} 106 107static void updateServiceRecordNative(JNIEnv *env, jobject object, 108 jint handle, 109 jbyteArray record) { 110 LOGV(__FUNCTION__); 111#ifdef HAVE_BLUETOOTH 112 if (conn != NULL) { 113 jbyte* c_record = env->GetByteArrayElements(record, NULL); 114 DBusMessage *reply = dbus_func_args(env, 115 conn, 116 BLUEZ_DBUS_BASE_PATH, 117 DBUS_CLASS_NAME, 118 "UpdateServiceRecord", 119 DBUS_TYPE_UINT32, &handle, 120 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, 121 &c_record, 122 env->GetArrayLength(record), 123 DBUS_TYPE_INVALID); 124 env->ReleaseByteArrayElements(record, c_record, JNI_ABORT); 125 } 126#endif 127} 128 129static void updateServiceRecordFromXmlNative(JNIEnv *env, jobject object, 130 jint handle, 131 jstring record) { 132 LOGV(__FUNCTION__); 133#ifdef HAVE_BLUETOOTH 134 if (conn != NULL) { 135 const char *c_record = env->GetStringUTFChars(record, NULL); 136 DBusMessage *reply = dbus_func_args(env, 137 conn, 138 BLUEZ_DBUS_BASE_PATH, 139 DBUS_CLASS_NAME, 140 "UpdateServiceRecordFromXML", 141 DBUS_TYPE_UINT32, &handle, 142 DBUS_TYPE_STRING, &c_record, 143 DBUS_TYPE_INVALID); 144 env->ReleaseStringUTFChars(record, c_record); 145 } 146#endif 147} 148 149/* private static native void removeServiceRecordNative(int handle); */ 150static void removeServiceRecordNative(JNIEnv *env, jobject object, 151 jint handle) { 152 LOGV(__FUNCTION__); 153#ifdef HAVE_BLUETOOTH 154 if (conn != NULL) { 155 DBusMessage *reply = dbus_func_args(env, 156 conn, 157 BLUEZ_DBUS_BASE_PATH, 158 DBUS_CLASS_NAME, 159 "RemoveServiceRecord", 160 DBUS_TYPE_UINT32, &handle, 161 DBUS_TYPE_INVALID); 162 } 163#endif 164} 165 166 167static JNINativeMethod sMethods[] = { 168 /* name, signature, funcPtr */ 169 {"classInitNative", "()V", (void*)classInitNative}, 170 {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative}, 171 {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative}, 172 {"addServiceRecordNative", "([B)I", (void*)addServiceRecordNative}, 173 {"addServiceRecordFromXmlNative", "(Ljava/lang/String;)I", (void*)addServiceRecordFromXmlNative}, 174 {"updateServiceRecordNative", "(I[B)V", (void*)updateServiceRecordNative}, 175 {"updateServiceRecordFromXmlNative", "(ILjava/lang/String;)V", (void*)updateServiceRecordFromXmlNative}, 176 {"removeServiceRecordNative", "(I)V", (void*)removeServiceRecordNative}, 177}; 178 179int register_android_bluetooth_Database(JNIEnv *env) { 180 return AndroidRuntime::registerNativeMethods(env, 181 "android/bluetooth/Database", sMethods, NELEM(sMethods)); 182} 183 184} /* namespace android */ 185