Merge "Add error codes for channel disconnection / connection."

This commit is contained in:
Jaikumar Ganesh
2011-09-09 15:19:43 -07:00
committed by Android (Google) Code Review
7 changed files with 150 additions and 64 deletions

View File

@@ -81,6 +81,20 @@ public final class BluetoothHealth implements BluetoothProfile {
*/
public static final int CHANNEL_TYPE_ANY = 12;
/** @hide */
public static final int HEALTH_OPERATION_SUCCESS = 6000;
/** @hide */
public static final int HEALTH_OPERATION_ERROR = 6001;
/** @hide */
public static final int HEALTH_OPERATION_INVALID_ARGS = 6002;
/** @hide */
public static final int HEALTH_OPERATION_GENERIC_FAILURE = 6003;
/** @hide */
public static final int HEALTH_OPERATION_NOT_FOUND = 6004;
/** @hide */
public static final int HEALTH_OPERATION_NOT_ALLOWED = 6005;
/**
* Register an application configuration that acts as a Health SINK.
* This is the configuration that will be used to communicate with health devices

View File

@@ -20,6 +20,7 @@ import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHealth;
import android.bluetooth.BluetoothInputDevice;
import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothProfile;
@@ -973,6 +974,22 @@ class BluetoothEventLoop {
}
}
/**
* Called by native code for the async response to a Connect
* method call to org.bluez.Health
*
* @param chanCode The internal id of the channel
* @param result Result code of the operation.
*/
private void onHealthDeviceConnectionResult(int chanCode, int result) {
log ("onHealthDeviceConnectionResult " + chanCode + " " + result);
// Success case gets handled by Property Change signal
if (result != BluetoothHealth.HEALTH_OPERATION_SUCCESS) {
mBluetoothService.onHealthDeviceChannelConnectionError(chanCode,
BluetoothHealth.STATE_CHANNEL_DISCONNECTED);
}
}
/**
* Called by native code on a DeviceDisconnected signal from
* org.bluez.NetworkServer.

View File

@@ -84,7 +84,6 @@ final class BluetoothHealthProfileHandler {
result = 31 * result + (mChannelPath == null ? 0 : mChannelPath.hashCode());
result = 31 * result + mDevice.hashCode();
result = 31 * result + mConfig.hashCode();
result = 31 * result + mState;
result = 31 * result + mChannelType;
return result;
}
@@ -152,7 +151,7 @@ final class BluetoothHealthProfileHandler {
String channelType = getStringChannelType(chan.mChannelType);
if (!mBluetoothService.createChannelNative(deviceObjectPath, configPath,
channelType)) {
channelType, chan.hashCode())) {
int prevState = chan.mState;
int state = BluetoothHealth.STATE_CHANNEL_DISCONNECTED;
callHealthChannelCallback(chan.mConfig, chan.mDevice, prevState, state, null,
@@ -258,7 +257,7 @@ final class BluetoothHealthProfileHandler {
boolean disconnectChannel(BluetoothDevice device,
BluetoothHealthAppConfiguration config, int id) {
HealthChannel chan = findChannelById(device, config, id);
HealthChannel chan = findChannelById(id);
if (chan == null) {
return false;
}
@@ -273,7 +272,8 @@ final class BluetoothHealthProfileHandler {
callHealthChannelCallback(config, device, prevState, chan.mState,
null, chan.hashCode());
if (!mBluetoothService.destroyChannelNative(deviceObjectPath, chan.mChannelPath)) {
if (!mBluetoothService.destroyChannelNative(deviceObjectPath, chan.mChannelPath,
chan.hashCode())) {
prevState = chan.mState;
chan.mState = BluetoothHealth.STATE_CHANNEL_CONNECTED;
callHealthChannelCallback(config, device, prevState, chan.mState,
@@ -284,8 +284,7 @@ final class BluetoothHealthProfileHandler {
}
}
private HealthChannel findChannelById(BluetoothDevice device,
BluetoothHealthAppConfiguration config, int id) {
private HealthChannel findChannelById(int id) {
for (HealthChannel chan : mHealthChannels) {
if (chan.hashCode() == id) return chan;
}
@@ -384,6 +383,15 @@ final class BluetoothHealthProfileHandler {
}
}
/*package*/ void onHealthDeviceChannelConnectionError(int chanCode,
int state) {
HealthChannel channel = findChannelById(chanCode);
if (channel == null) errorLog("No record of this channel:" + chanCode);
callHealthChannelCallback(channel.mConfig, channel.mDevice, channel.mState, state, null,
chanCode);
}
private BluetoothHealthAppConfiguration findHealthApplication(
BluetoothDevice device, String channelPath) {
BluetoothHealthAppConfiguration config = null;
@@ -424,9 +432,19 @@ final class BluetoothHealthProfileHandler {
config = findHealthApplication(device, channelPath);
if (exists) {
channel = findConnectingChannel(device, config);
if (channel == null) {
channel = new HealthChannel(device, config, null, false,
channelPath);
channel.mState = BluetoothHealth.STATE_CHANNEL_DISCONNECTED;
mHealthChannels.add(channel);
}
channel.mChannelPath = channelPath;
fd = mBluetoothService.getChannelFdNative(channelPath);
if (fd == null) {
errorLog("Error obtaining fd for channel:" + channelPath);
disconnectChannel(device, config, channel.hashCode());
return;
}
boolean mainChannel =
@@ -440,18 +458,10 @@ final class BluetoothHealthProfileHandler {
}
if (mainChannelPath.equals(channelPath)) mainChannel = true;
}
channel = findConnectingChannel(device, config);
if (channel != null) {
channel.mChannelFd = fd;
channel.mMainChannel = mainChannel;
channel.mChannelPath = channelPath;
prevState = channel.mState;
} else {
channel = new HealthChannel(device, config, fd, mainChannel,
channelPath);
mHealthChannels.add(channel);
prevState = BluetoothHealth.STATE_CHANNEL_DISCONNECTED;
}
channel.mChannelFd = fd;
channel.mMainChannel = mainChannel;
prevState = channel.mState;
state = BluetoothHealth.STATE_CHANNEL_CONNECTED;
} else {
channel = findChannelByPath(device, channelPath);

View File

@@ -2255,6 +2255,14 @@ public class BluetoothService extends IBluetooth.Stub {
}
}
/*package*/ void onHealthDeviceChannelConnectionError(int channelCode,
int newState) {
synchronized(mBluetoothHealthProfileHandler) {
mBluetoothHealthProfileHandler.onHealthDeviceChannelConnectionError(channelCode,
newState);
}
}
public int getHealthDeviceConnectionState(BluetoothDevice device) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
"Need BLUETOOTH permission");
@@ -2785,8 +2793,9 @@ public class BluetoothService extends IBluetooth.Stub {
String channelType);
native String registerHealthApplicationNative(int dataType, String role, String name);
native boolean unregisterHealthApplicationNative(String path);
native boolean createChannelNative(String devicePath, String appPath, String channelType);
native boolean destroyChannelNative(String devicePath, String channelpath);
native boolean createChannelNative(String devicePath, String appPath, String channelType,
int code);
native boolean destroyChannelNative(String devicePath, String channelpath, int code);
native String getMainChannelNative(String path);
native String getChannelApplicationNative(String channelPath);
native ParcelFileDescriptor getChannelFdNative(String channelPath);

View File

@@ -202,6 +202,13 @@ bool debug_no_encrypt();
#define INPUT_OPERATION_GENERIC_FAILURE 5003
#define INPUT_OPERATION_SUCCESS 5004
#define HEALTH_OPERATION_SUCCESS 6000
#define HEALTH_OPERATION_ERROR 6001
#define HEALTH_OPERATION_INVALID_ARGS 6002
#define HEALTH_OPERATION_GENERIC_FAILURE 6003
#define HEALTH_OPERATION_NOT_FOUND 6004
#define HEALTH_OPERATION_NOT_ALLOWED 6005
#endif
} /* namespace android */

View File

@@ -74,6 +74,7 @@ static jmethodID method_onPanDevicePropertyChanged;
static jmethodID method_onPanDeviceConnectionResult;
static jmethodID method_onHealthDevicePropertyChanged;
static jmethodID method_onHealthDeviceChannelChanged;
static jmethodID method_onHealthDeviceConnectionResult;
typedef event_loop_native_data_t native_data_t;
@@ -141,6 +142,9 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
"(Ljava/lang/String;[Ljava/lang/String;)V");
method_onPanDeviceConnectionResult = env->GetMethodID(clazz, "onPanDeviceConnectionResult",
"(Ljava/lang/String;I)V");
method_onHealthDeviceConnectionResult = env->GetMethodID(clazz,
"onHealthDeviceConnectionResult",
"(II)V");
method_onHealthDevicePropertyChanged = env->GetMethodID(clazz, "onHealthDevicePropertyChanged",
"(Ljava/lang/String;[Ljava/lang/String;)V");
method_onHealthDeviceChannelChanged = env->GetMethodID(clazz, "onHealthDeviceChannelChanged",
@@ -1533,6 +1537,39 @@ void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
free(user);
}
void onHealthDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
DBusError err;
dbus_error_init(&err);
JNIEnv *env;
nat->vm->GetEnv((void**)&env, nat->envVer);
jint result = HEALTH_OPERATION_SUCCESS;
if (dbus_set_error_from_message(&err, msg)) {
if (!strcmp(err.name, BLUEZ_ERROR_IFC ".InvalidArgs")) {
result = HEALTH_OPERATION_INVALID_ARGS;
} else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".HealthError")) {
result = HEALTH_OPERATION_ERROR;
} else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotFound")) {
result = HEALTH_OPERATION_NOT_FOUND;
} else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotAllowed")) {
result = HEALTH_OPERATION_NOT_ALLOWED;
} else {
result = HEALTH_OPERATION_GENERIC_FAILURE;
}
LOG_AND_FREE_DBUS_ERROR(&err);
}
LOGV("... Health Device Code = %d, result = %d", code, result);
jint code = *(int *) user;
env->CallVoidMethod(nat->me,
method_onHealthDeviceConnectionResult,
code,
result);
free(user);
}
#endif
static JNINativeMethod sMethods[] = {

View File

@@ -78,8 +78,8 @@ void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *nat);
void onDiscoverServicesResult(DBusMessage *msg, void *user, void *nat);
void onCreateDeviceResult(DBusMessage *msg, void *user, void *nat);
void onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
void onConnectPanResult(DBusMessage *msg, void *user, void *n);
void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
void onHealthDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
/** Get native data stored in the opaque (Java code maintained) pointer mNativeData
@@ -1450,79 +1450,70 @@ static jboolean unregisterHealthApplicationNative(JNIEnv *env, jobject object,
}
static jboolean createChannelNative(JNIEnv *env, jobject object,
jstring devicePath, jstring appPath, jstring config) {
jstring devicePath, jstring appPath, jstring config,
jint code) {
LOGV("%s", __FUNCTION__);
jboolean result = JNI_FALSE;
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
struct event_loop_native_data_t *eventLoopNat =
get_EventLoop_native_data(env, eventLoop);
if (nat) {
DBusError err;
dbus_error_init(&err);
if (nat && eventLoopNat) {
const char *c_device_path = env->GetStringUTFChars(devicePath, NULL);
const char *c_app_path = env->GetStringUTFChars(appPath, NULL);
const char *c_config = env->GetStringUTFChars(config, NULL);
int *data = (int *) malloc(sizeof(int));
if (data == NULL) return JNI_FALSE;
DBusMessage *reply = dbus_func_args(env, nat->conn,
c_device_path,
DBUS_HEALTH_DEVICE_IFACE,
"CreateChannel",
DBUS_TYPE_OBJECT_PATH, &c_app_path,
DBUS_TYPE_STRING, &c_config,
DBUS_TYPE_INVALID);
*data = code;
bool ret = dbus_func_args_async(env, nat->conn, -1, onHealthDeviceConnectionResult,
data, eventLoopNat, c_device_path,
DBUS_HEALTH_DEVICE_IFACE, "CreateChannel",
DBUS_TYPE_OBJECT_PATH, &c_app_path,
DBUS_TYPE_STRING, &c_config,
DBUS_TYPE_INVALID);
env->ReleaseStringUTFChars(devicePath, c_device_path);
env->ReleaseStringUTFChars(appPath, c_app_path);
env->ReleaseStringUTFChars(config, c_config);
if (!reply) {
if (dbus_error_is_set(&err)) {
LOG_AND_FREE_DBUS_ERROR(&err);
}
} else {
result = JNI_TRUE;
}
return ret ? JNI_TRUE : JNI_FALSE;
}
#endif
return result;
return JNI_FALSE;
}
static jboolean destroyChannelNative(JNIEnv *env, jobject object, jstring devicePath,
jstring channelPath) {
jstring channelPath, jint code) {
LOGE("%s", __FUNCTION__);
jboolean result = JNI_FALSE;
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
struct event_loop_native_data_t *eventLoopNat =
get_EventLoop_native_data(env, eventLoop);
if (nat) {
DBusError err;
dbus_error_init(&err);
if (nat && eventLoopNat) {
const char *c_device_path = env->GetStringUTFChars(devicePath, NULL);
const char *c_channel_path = env->GetStringUTFChars(channelPath, NULL);
int *data = (int *) malloc(sizeof(int));
if (data == NULL) return JNI_FALSE;
DBusMessage *reply = dbus_func_args(env, nat->conn,
c_device_path,
DBUS_HEALTH_DEVICE_IFACE,
"DestroyChannel",
DBUS_TYPE_OBJECT_PATH, &c_channel_path,
DBUS_TYPE_INVALID);
*data = code;
bool ret = dbus_func_args_async(env, nat->conn, -1, onHealthDeviceConnectionResult,
data, eventLoopNat, c_device_path,
DBUS_HEALTH_DEVICE_IFACE, "DestroyChannel",
DBUS_TYPE_OBJECT_PATH, &c_channel_path,
DBUS_TYPE_INVALID);
env->ReleaseStringUTFChars(devicePath, c_device_path);
env->ReleaseStringUTFChars(channelPath, c_channel_path);
if (!reply) {
if (dbus_error_is_set(&err)) {
LOG_AND_FREE_DBUS_ERROR(&err);
}
} else {
result = JNI_TRUE;
}
return ret ? JNI_TRUE : JNI_FALSE;
}
#endif
return result;
return JNI_FALSE;
}
static jstring getMainChannelNative(JNIEnv *env, jobject object, jstring devicePath) {
@@ -1755,9 +1746,10 @@ static JNINativeMethod sMethods[] = {
{"unregisterHealthApplicationNative", "(Ljava/lang/String;)Z",
(void *)unregisterHealthApplicationNative},
{"createChannelNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z",
{"createChannelNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Z",
(void *)createChannelNative},
{"destroyChannelNative", "(Ljava/lang/String;Ljava/lang/String;)Z", (void *)destroyChannelNative},
{"destroyChannelNative", "(Ljava/lang/String;Ljava/lang/String;I)Z",
(void *)destroyChannelNative},
{"getMainChannelNative", "(Ljava/lang/String;)Ljava/lang/String;", (void *)getMainChannelNative},
{"getChannelApplicationNative", "(Ljava/lang/String;)Ljava/lang/String;",
(void *)getChannelApplicationNative},