Skip to content

Commit 6d172e6

Browse files
Jaikumar GaneshAndroid (Google) Code Review
authored andcommitted
Merge "Add error codes for channel disconnection / connection."
2 parents 4eb37f8 + b5d2d45 commit 6d172e6

File tree

7 files changed

+152
-66
lines changed

7 files changed

+152
-66
lines changed

core/java/android/bluetooth/BluetoothHealth.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,20 @@ public final class BluetoothHealth implements BluetoothProfile {
8181
*/
8282
public static final int CHANNEL_TYPE_ANY = 12;
8383

84+
/** @hide */
85+
public static final int HEALTH_OPERATION_SUCCESS = 6000;
86+
/** @hide */
87+
public static final int HEALTH_OPERATION_ERROR = 6001;
88+
/** @hide */
89+
public static final int HEALTH_OPERATION_INVALID_ARGS = 6002;
90+
/** @hide */
91+
public static final int HEALTH_OPERATION_GENERIC_FAILURE = 6003;
92+
/** @hide */
93+
public static final int HEALTH_OPERATION_NOT_FOUND = 6004;
94+
/** @hide */
95+
public static final int HEALTH_OPERATION_NOT_ALLOWED = 6005;
96+
97+
8498
/**
8599
* Register an application configuration that acts as a Health SINK.
86100
* This is the configuration that will be used to communicate with health devices

core/java/android/server/BluetoothEventLoop.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import android.bluetooth.BluetoothAdapter;
2121
import android.bluetooth.BluetoothClass;
2222
import android.bluetooth.BluetoothDevice;
23+
import android.bluetooth.BluetoothHealth;
2324
import android.bluetooth.BluetoothInputDevice;
2425
import android.bluetooth.BluetoothPan;
2526
import android.bluetooth.BluetoothProfile;
@@ -973,6 +974,22 @@ private void onPanDeviceConnectionResult(String path, int result) {
973974
}
974975
}
975976

977+
/**
978+
* Called by native code for the async response to a Connect
979+
* method call to org.bluez.Health
980+
*
981+
* @param chanCode The internal id of the channel
982+
* @param result Result code of the operation.
983+
*/
984+
private void onHealthDeviceConnectionResult(int chanCode, int result) {
985+
log ("onHealthDeviceConnectionResult " + chanCode + " " + result);
986+
// Success case gets handled by Property Change signal
987+
if (result != BluetoothHealth.HEALTH_OPERATION_SUCCESS) {
988+
mBluetoothService.onHealthDeviceChannelConnectionError(chanCode,
989+
BluetoothHealth.STATE_CHANNEL_DISCONNECTED);
990+
}
991+
}
992+
976993
/**
977994
* Called by native code on a DeviceDisconnected signal from
978995
* org.bluez.NetworkServer.

core/java/android/server/BluetoothHealthProfileHandler.java

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ public int hashCode() {
8484
result = 31 * result + (mChannelPath == null ? 0 : mChannelPath.hashCode());
8585
result = 31 * result + mDevice.hashCode();
8686
result = 31 * result + mConfig.hashCode();
87-
result = 31 * result + mState;
8887
result = 31 * result + mChannelType;
8988
return result;
9089
}
@@ -152,7 +151,7 @@ public void handleMessage(Message msg) {
152151
String channelType = getStringChannelType(chan.mChannelType);
153152

154153
if (!mBluetoothService.createChannelNative(deviceObjectPath, configPath,
155-
channelType)) {
154+
channelType, chan.hashCode())) {
156155
int prevState = chan.mState;
157156
int state = BluetoothHealth.STATE_CHANNEL_DISCONNECTED;
158157
callHealthChannelCallback(chan.mConfig, chan.mDevice, prevState, state, null,
@@ -258,7 +257,7 @@ private String getStringRole(int role) {
258257

259258
boolean disconnectChannel(BluetoothDevice device,
260259
BluetoothHealthAppConfiguration config, int id) {
261-
HealthChannel chan = findChannelById(device, config, id);
260+
HealthChannel chan = findChannelById(id);
262261
if (chan == null) {
263262
return false;
264263
}
@@ -273,7 +272,8 @@ boolean disconnectChannel(BluetoothDevice device,
273272
callHealthChannelCallback(config, device, prevState, chan.mState,
274273
null, chan.hashCode());
275274

276-
if (!mBluetoothService.destroyChannelNative(deviceObjectPath, chan.mChannelPath)) {
275+
if (!mBluetoothService.destroyChannelNative(deviceObjectPath, chan.mChannelPath,
276+
chan.hashCode())) {
277277
prevState = chan.mState;
278278
chan.mState = BluetoothHealth.STATE_CHANNEL_CONNECTED;
279279
callHealthChannelCallback(config, device, prevState, chan.mState,
@@ -284,8 +284,7 @@ boolean disconnectChannel(BluetoothDevice device,
284284
}
285285
}
286286

287-
private HealthChannel findChannelById(BluetoothDevice device,
288-
BluetoothHealthAppConfiguration config, int id) {
287+
private HealthChannel findChannelById(int id) {
289288
for (HealthChannel chan : mHealthChannels) {
290289
if (chan.hashCode() == id) return chan;
291290
}
@@ -384,6 +383,15 @@ ParcelFileDescriptor getMainChannelFd(BluetoothDevice device,
384383
}
385384
}
386385

386+
/*package*/ void onHealthDeviceChannelConnectionError(int chanCode,
387+
int state) {
388+
HealthChannel channel = findChannelById(chanCode);
389+
if (channel == null) errorLog("No record of this channel:" + chanCode);
390+
391+
callHealthChannelCallback(channel.mConfig, channel.mDevice, channel.mState, state, null,
392+
chanCode);
393+
}
394+
387395
private BluetoothHealthAppConfiguration findHealthApplication(
388396
BluetoothDevice device, String channelPath) {
389397
BluetoothHealthAppConfiguration config = null;
@@ -424,9 +432,19 @@ private BluetoothHealthAppConfiguration findHealthApplication(
424432
config = findHealthApplication(device, channelPath);
425433

426434
if (exists) {
435+
channel = findConnectingChannel(device, config);
436+
if (channel == null) {
437+
channel = new HealthChannel(device, config, null, false,
438+
channelPath);
439+
channel.mState = BluetoothHealth.STATE_CHANNEL_DISCONNECTED;
440+
mHealthChannels.add(channel);
441+
}
442+
channel.mChannelPath = channelPath;
443+
427444
fd = mBluetoothService.getChannelFdNative(channelPath);
428445
if (fd == null) {
429446
errorLog("Error obtaining fd for channel:" + channelPath);
447+
disconnectChannel(device, config, channel.hashCode());
430448
return;
431449
}
432450
boolean mainChannel =
@@ -440,18 +458,10 @@ private BluetoothHealthAppConfiguration findHealthApplication(
440458
}
441459
if (mainChannelPath.equals(channelPath)) mainChannel = true;
442460
}
443-
channel = findConnectingChannel(device, config);
444-
if (channel != null) {
445-
channel.mChannelFd = fd;
446-
channel.mMainChannel = mainChannel;
447-
channel.mChannelPath = channelPath;
448-
prevState = channel.mState;
449-
} else {
450-
channel = new HealthChannel(device, config, fd, mainChannel,
451-
channelPath);
452-
mHealthChannels.add(channel);
453-
prevState = BluetoothHealth.STATE_CHANNEL_DISCONNECTED;
454-
}
461+
462+
channel.mChannelFd = fd;
463+
channel.mMainChannel = mainChannel;
464+
prevState = channel.mState;
455465
state = BluetoothHealth.STATE_CHANNEL_CONNECTED;
456466
} else {
457467
channel = findChannelByPath(device, channelPath);

core/java/android/server/BluetoothService.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2255,6 +2255,14 @@ public ParcelFileDescriptor getMainChannelFd(BluetoothDevice device,
22552255
}
22562256
}
22572257

2258+
/*package*/ void onHealthDeviceChannelConnectionError(int channelCode,
2259+
int newState) {
2260+
synchronized(mBluetoothHealthProfileHandler) {
2261+
mBluetoothHealthProfileHandler.onHealthDeviceChannelConnectionError(channelCode,
2262+
newState);
2263+
}
2264+
}
2265+
22582266
public int getHealthDeviceConnectionState(BluetoothDevice device) {
22592267
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
22602268
"Need BLUETOOTH permission");
@@ -2785,8 +2793,9 @@ native String registerHealthApplicationNative(int dataType, String role, String
27852793
String channelType);
27862794
native String registerHealthApplicationNative(int dataType, String role, String name);
27872795
native boolean unregisterHealthApplicationNative(String path);
2788-
native boolean createChannelNative(String devicePath, String appPath, String channelType);
2789-
native boolean destroyChannelNative(String devicePath, String channelpath);
2796+
native boolean createChannelNative(String devicePath, String appPath, String channelType,
2797+
int code);
2798+
native boolean destroyChannelNative(String devicePath, String channelpath, int code);
27902799
native String getMainChannelNative(String path);
27912800
native String getChannelApplicationNative(String channelPath);
27922801
native ParcelFileDescriptor getChannelFdNative(String channelPath);

core/jni/android_bluetooth_common.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,13 @@ bool debug_no_encrypt();
202202
#define INPUT_OPERATION_GENERIC_FAILURE 5003
203203
#define INPUT_OPERATION_SUCCESS 5004
204204

205+
#define HEALTH_OPERATION_SUCCESS 6000
206+
#define HEALTH_OPERATION_ERROR 6001
207+
#define HEALTH_OPERATION_INVALID_ARGS 6002
208+
#define HEALTH_OPERATION_GENERIC_FAILURE 6003
209+
#define HEALTH_OPERATION_NOT_FOUND 6004
210+
#define HEALTH_OPERATION_NOT_ALLOWED 6005
211+
205212
#endif
206213
} /* namespace android */
207214

core/jni/android_server_BluetoothEventLoop.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ static jmethodID method_onPanDevicePropertyChanged;
7474
static jmethodID method_onPanDeviceConnectionResult;
7575
static jmethodID method_onHealthDevicePropertyChanged;
7676
static jmethodID method_onHealthDeviceChannelChanged;
77+
static jmethodID method_onHealthDeviceConnectionResult;
7778

7879
typedef event_loop_native_data_t native_data_t;
7980

@@ -141,6 +142,9 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
141142
"(Ljava/lang/String;[Ljava/lang/String;)V");
142143
method_onPanDeviceConnectionResult = env->GetMethodID(clazz, "onPanDeviceConnectionResult",
143144
"(Ljava/lang/String;I)V");
145+
method_onHealthDeviceConnectionResult = env->GetMethodID(clazz,
146+
"onHealthDeviceConnectionResult",
147+
"(II)V");
144148
method_onHealthDevicePropertyChanged = env->GetMethodID(clazz, "onHealthDevicePropertyChanged",
145149
"(Ljava/lang/String;[Ljava/lang/String;)V");
146150
method_onHealthDeviceChannelChanged = env->GetMethodID(clazz, "onHealthDeviceChannelChanged",
@@ -1533,6 +1537,39 @@ void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
15331537
free(user);
15341538
}
15351539

1540+
void onHealthDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
1541+
LOGV("%s", __FUNCTION__);
1542+
1543+
native_data_t *nat = (native_data_t *)n;
1544+
DBusError err;
1545+
dbus_error_init(&err);
1546+
JNIEnv *env;
1547+
nat->vm->GetEnv((void**)&env, nat->envVer);
1548+
1549+
jint result = HEALTH_OPERATION_SUCCESS;
1550+
if (dbus_set_error_from_message(&err, msg)) {
1551+
if (!strcmp(err.name, BLUEZ_ERROR_IFC ".InvalidArgs")) {
1552+
result = HEALTH_OPERATION_INVALID_ARGS;
1553+
} else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".HealthError")) {
1554+
result = HEALTH_OPERATION_ERROR;
1555+
} else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotFound")) {
1556+
result = HEALTH_OPERATION_NOT_FOUND;
1557+
} else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotAllowed")) {
1558+
result = HEALTH_OPERATION_NOT_ALLOWED;
1559+
} else {
1560+
result = HEALTH_OPERATION_GENERIC_FAILURE;
1561+
}
1562+
LOG_AND_FREE_DBUS_ERROR(&err);
1563+
}
1564+
1565+
LOGV("... Health Device Code = %d, result = %d", code, result);
1566+
jint code = *(int *) user;
1567+
env->CallVoidMethod(nat->me,
1568+
method_onHealthDeviceConnectionResult,
1569+
code,
1570+
result);
1571+
free(user);
1572+
}
15361573
#endif
15371574

15381575
static JNINativeMethod sMethods[] = {

core/jni/android_server_BluetoothService.cpp

Lines changed: 38 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *nat);
7878
void onDiscoverServicesResult(DBusMessage *msg, void *user, void *nat);
7979
void onCreateDeviceResult(DBusMessage *msg, void *user, void *nat);
8080
void onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
81-
void onConnectPanResult(DBusMessage *msg, void *user, void *n);
8281
void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
82+
void onHealthDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
8383

8484

8585
/** Get native data stored in the opaque (Java code maintained) pointer mNativeData
@@ -1450,79 +1450,70 @@ static jboolean unregisterHealthApplicationNative(JNIEnv *env, jobject object,
14501450
}
14511451

14521452
static jboolean createChannelNative(JNIEnv *env, jobject object,
1453-
jstring devicePath, jstring appPath, jstring config) {
1453+
jstring devicePath, jstring appPath, jstring config,
1454+
jint code) {
14541455
LOGV("%s", __FUNCTION__);
1455-
jboolean result = JNI_FALSE;
14561456
#ifdef HAVE_BLUETOOTH
14571457
native_data_t *nat = get_native_data(env, object);
1458+
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
1459+
struct event_loop_native_data_t *eventLoopNat =
1460+
get_EventLoop_native_data(env, eventLoop);
14581461

1459-
if (nat) {
1460-
DBusError err;
1461-
dbus_error_init(&err);
1462-
1462+
if (nat && eventLoopNat) {
14631463
const char *c_device_path = env->GetStringUTFChars(devicePath, NULL);
14641464
const char *c_app_path = env->GetStringUTFChars(appPath, NULL);
14651465
const char *c_config = env->GetStringUTFChars(config, NULL);
1466-
1467-
DBusMessage *reply = dbus_func_args(env, nat->conn,
1468-
c_device_path,
1469-
DBUS_HEALTH_DEVICE_IFACE,
1470-
"CreateChannel",
1471-
DBUS_TYPE_OBJECT_PATH, &c_app_path,
1472-
DBUS_TYPE_STRING, &c_config,
1473-
DBUS_TYPE_INVALID);
1466+
int *data = (int *) malloc(sizeof(int));
1467+
if (data == NULL) return JNI_FALSE;
1468+
1469+
*data = code;
1470+
bool ret = dbus_func_args_async(env, nat->conn, -1, onHealthDeviceConnectionResult,
1471+
data, eventLoopNat, c_device_path,
1472+
DBUS_HEALTH_DEVICE_IFACE, "CreateChannel",
1473+
DBUS_TYPE_OBJECT_PATH, &c_app_path,
1474+
DBUS_TYPE_STRING, &c_config,
1475+
DBUS_TYPE_INVALID);
14741476

14751477

14761478
env->ReleaseStringUTFChars(devicePath, c_device_path);
14771479
env->ReleaseStringUTFChars(appPath, c_app_path);
14781480
env->ReleaseStringUTFChars(config, c_config);
14791481

1480-
if (!reply) {
1481-
if (dbus_error_is_set(&err)) {
1482-
LOG_AND_FREE_DBUS_ERROR(&err);
1483-
}
1484-
} else {
1485-
result = JNI_TRUE;
1486-
}
1482+
return ret ? JNI_TRUE : JNI_FALSE;
14871483
}
14881484
#endif
1489-
return result;
1485+
return JNI_FALSE;
14901486
}
14911487

14921488
static jboolean destroyChannelNative(JNIEnv *env, jobject object, jstring devicePath,
1493-
jstring channelPath) {
1489+
jstring channelPath, jint code) {
14941490
LOGE("%s", __FUNCTION__);
1495-
jboolean result = JNI_FALSE;
14961491
#ifdef HAVE_BLUETOOTH
14971492
native_data_t *nat = get_native_data(env, object);
1493+
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
1494+
struct event_loop_native_data_t *eventLoopNat =
1495+
get_EventLoop_native_data(env, eventLoop);
14981496

1499-
if (nat) {
1500-
DBusError err;
1501-
dbus_error_init(&err);
1502-
1497+
if (nat && eventLoopNat) {
15031498
const char *c_device_path = env->GetStringUTFChars(devicePath, NULL);
15041499
const char *c_channel_path = env->GetStringUTFChars(channelPath, NULL);
1505-
1506-
DBusMessage *reply = dbus_func_args(env, nat->conn,
1507-
c_device_path,
1508-
DBUS_HEALTH_DEVICE_IFACE,
1509-
"DestroyChannel",
1510-
DBUS_TYPE_OBJECT_PATH, &c_channel_path,
1511-
DBUS_TYPE_INVALID);
1500+
int *data = (int *) malloc(sizeof(int));
1501+
if (data == NULL) return JNI_FALSE;
1502+
1503+
*data = code;
1504+
bool ret = dbus_func_args_async(env, nat->conn, -1, onHealthDeviceConnectionResult,
1505+
data, eventLoopNat, c_device_path,
1506+
DBUS_HEALTH_DEVICE_IFACE, "DestroyChannel",
1507+
DBUS_TYPE_OBJECT_PATH, &c_channel_path,
1508+
DBUS_TYPE_INVALID);
15121509

15131510
env->ReleaseStringUTFChars(devicePath, c_device_path);
15141511
env->ReleaseStringUTFChars(channelPath, c_channel_path);
15151512

1516-
if (!reply) {
1517-
if (dbus_error_is_set(&err)) {
1518-
LOG_AND_FREE_DBUS_ERROR(&err);
1519-
}
1520-
} else {
1521-
result = JNI_TRUE;
1522-
}
1513+
return ret ? JNI_TRUE : JNI_FALSE;
15231514
}
15241515
#endif
1525-
return result;
1516+
return JNI_FALSE;
15261517
}
15271518

15281519
static jstring getMainChannelNative(JNIEnv *env, jobject object, jstring devicePath) {
@@ -1755,9 +1746,10 @@ static JNINativeMethod sMethods[] = {
17551746

17561747
{"unregisterHealthApplicationNative", "(Ljava/lang/String;)Z",
17571748
(void *)unregisterHealthApplicationNative},
1758-
{"createChannelNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z",
1749+
{"createChannelNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Z",
17591750
(void *)createChannelNative},
1760-
{"destroyChannelNative", "(Ljava/lang/String;Ljava/lang/String;)Z", (void *)destroyChannelNative},
1751+
{"destroyChannelNative", "(Ljava/lang/String;Ljava/lang/String;I)Z",
1752+
(void *)destroyChannelNative},
17611753
{"getMainChannelNative", "(Ljava/lang/String;)Ljava/lang/String;", (void *)getMainChannelNative},
17621754
{"getChannelApplicationNative", "(Ljava/lang/String;)Ljava/lang/String;",
17631755
(void *)getChannelApplicationNative},

0 commit comments

Comments
 (0)