am d4c1baf9: Merge change 23646 into eclair
Merge commit 'd4c1baf93708ad4e90c556e6041a498dbffaaba0' into eclair-plus-aosp * commit 'd4c1baf93708ad4e90c556e6041a498dbffaaba0': Immediately destroy BluetoothSocket's on close().
This commit is contained in:
@@ -312,7 +312,7 @@ public final class BluetoothAdapter {
|
|||||||
BluetoothServerSocket socket = new BluetoothServerSocket(
|
BluetoothServerSocket socket = new BluetoothServerSocket(
|
||||||
BluetoothSocket.TYPE_RFCOMM, true, true, channel);
|
BluetoothSocket.TYPE_RFCOMM, true, true, channel);
|
||||||
try {
|
try {
|
||||||
socket.mSocket.bindListenNative();
|
socket.mSocket.bindListen();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
try {
|
try {
|
||||||
socket.close();
|
socket.close();
|
||||||
@@ -334,7 +334,7 @@ public final class BluetoothAdapter {
|
|||||||
BluetoothServerSocket socket = new BluetoothServerSocket(
|
BluetoothServerSocket socket = new BluetoothServerSocket(
|
||||||
BluetoothSocket.TYPE_RFCOMM, false, false, port);
|
BluetoothSocket.TYPE_RFCOMM, false, false, port);
|
||||||
try {
|
try {
|
||||||
socket.mSocket.bindListenNative();
|
socket.mSocket.bindListen();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
try {
|
try {
|
||||||
socket.close();
|
socket.close();
|
||||||
@@ -356,7 +356,7 @@ public final class BluetoothAdapter {
|
|||||||
BluetoothServerSocket socket = new BluetoothServerSocket(
|
BluetoothServerSocket socket = new BluetoothServerSocket(
|
||||||
BluetoothSocket.TYPE_SCO, false, false, -1);
|
BluetoothSocket.TYPE_SCO, false, false, -1);
|
||||||
try {
|
try {
|
||||||
socket.mSocket.bindListenNative();
|
socket.mSocket.bindListen();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
try {
|
try {
|
||||||
socket.close();
|
socket.close();
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import java.io.InputStream;
|
|||||||
* Return number of bytes available before this stream will block.
|
* Return number of bytes available before this stream will block.
|
||||||
*/
|
*/
|
||||||
public int available() throws IOException {
|
public int available() throws IOException {
|
||||||
return mSocket.availableNative();
|
return mSocket.available();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
@@ -57,7 +57,7 @@ import java.io.InputStream;
|
|||||||
*/
|
*/
|
||||||
public int read() throws IOException {
|
public int read() throws IOException {
|
||||||
byte b[] = new byte[1];
|
byte b[] = new byte[1];
|
||||||
int ret = mSocket.readNative(b, 0, 1);
|
int ret = mSocket.read(b, 0, 1);
|
||||||
if (ret == 1) {
|
if (ret == 1) {
|
||||||
return (int)b[0] & 0xff;
|
return (int)b[0] & 0xff;
|
||||||
} else {
|
} else {
|
||||||
@@ -93,6 +93,6 @@ import java.io.InputStream;
|
|||||||
if ((offset | length) < 0 || length > b.length - offset) {
|
if ((offset | length) < 0 || length > b.length - offset) {
|
||||||
throw new ArrayIndexOutOfBoundsException("invalid offset or length");
|
throw new ArrayIndexOutOfBoundsException("invalid offset or length");
|
||||||
}
|
}
|
||||||
return mSocket.readNative(b, offset, length);
|
return mSocket.read(b, offset, length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ import java.io.OutputStream;
|
|||||||
public void write(int oneByte) throws IOException {
|
public void write(int oneByte) throws IOException {
|
||||||
byte b[] = new byte[1];
|
byte b[] = new byte[1];
|
||||||
b[0] = (byte)oneByte;
|
b[0] = (byte)oneByte;
|
||||||
mSocket.writeNative(b, 0, 1);
|
mSocket.write(b, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,6 +82,6 @@ import java.io.OutputStream;
|
|||||||
if ((offset | count) < 0 || count > b.length - offset) {
|
if ((offset | count) < 0 || count > b.length - offset) {
|
||||||
throw new IndexOutOfBoundsException("invalid offset or length");
|
throw new IndexOutOfBoundsException("invalid offset or length");
|
||||||
}
|
}
|
||||||
mSocket.writeNative(b, offset, count);
|
mSocket.write(b, offset, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import java.io.IOException;
|
|||||||
* operations and close the socket.
|
* operations and close the socket.
|
||||||
*/
|
*/
|
||||||
public final class BluetoothServerSocket implements Closeable {
|
public final class BluetoothServerSocket implements Closeable {
|
||||||
|
|
||||||
/*package*/ final BluetoothSocket mSocket;
|
/*package*/ final BluetoothSocket mSocket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,7 +89,7 @@ public final class BluetoothServerSocket implements Closeable {
|
|||||||
* timeout
|
* timeout
|
||||||
*/
|
*/
|
||||||
public BluetoothSocket accept(int timeout) throws IOException {
|
public BluetoothSocket accept(int timeout) throws IOException {
|
||||||
return mSocket.acceptNative(timeout);
|
return mSocket.accept(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -97,6 +98,6 @@ public final class BluetoothServerSocket implements Closeable {
|
|||||||
* throw an IOException.
|
* throw an IOException.
|
||||||
*/
|
*/
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
mSocket.closeNative();
|
mSocket.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A connected or connecting Bluetooth socket.
|
* A connected or connecting Bluetooth socket.
|
||||||
*
|
*
|
||||||
@@ -63,7 +65,14 @@ public final class BluetoothSocket implements Closeable {
|
|||||||
private final BluetoothInputStream mInputStream;
|
private final BluetoothInputStream mInputStream;
|
||||||
private final BluetoothOutputStream mOutputStream;
|
private final BluetoothOutputStream mOutputStream;
|
||||||
|
|
||||||
private int mSocketData; /* used by native code only */
|
/** prevents all native calls after destroyNative() */
|
||||||
|
private boolean mClosed;
|
||||||
|
|
||||||
|
/** protects mClosed */
|
||||||
|
private final ReentrantReadWriteLock mLock;
|
||||||
|
|
||||||
|
/** used by native code only */
|
||||||
|
private int mSocketData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a BluetoothSocket.
|
* Construct a BluetoothSocket.
|
||||||
@@ -95,6 +104,8 @@ public final class BluetoothSocket implements Closeable {
|
|||||||
}
|
}
|
||||||
mInputStream = new BluetoothInputStream(this);
|
mInputStream = new BluetoothInputStream(this);
|
||||||
mOutputStream = new BluetoothOutputStream(this);
|
mOutputStream = new BluetoothOutputStream(this);
|
||||||
|
mClosed = false;
|
||||||
|
mLock = new ReentrantReadWriteLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -132,7 +143,13 @@ public final class BluetoothSocket implements Closeable {
|
|||||||
* @throws IOException on error, for example connection failure
|
* @throws IOException on error, for example connection failure
|
||||||
*/
|
*/
|
||||||
public void connect() throws IOException {
|
public void connect() throws IOException {
|
||||||
connectNative();
|
mLock.readLock().lock();
|
||||||
|
try {
|
||||||
|
if (mClosed) throw new IOException("socket closed");
|
||||||
|
connectNative();
|
||||||
|
} finally {
|
||||||
|
mLock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -141,7 +158,24 @@ public final class BluetoothSocket implements Closeable {
|
|||||||
* throw an IOException.
|
* throw an IOException.
|
||||||
*/
|
*/
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
closeNative();
|
// abort blocking operations on the socket
|
||||||
|
mLock.readLock().lock();
|
||||||
|
try {
|
||||||
|
if (mClosed) return;
|
||||||
|
abortNative();
|
||||||
|
} finally {
|
||||||
|
mLock.readLock().unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// all native calls are guarenteed to immediately return after
|
||||||
|
// abortNative(), so this lock should immediatley acquire
|
||||||
|
mLock.writeLock().lock();
|
||||||
|
try {
|
||||||
|
mClosed = true;
|
||||||
|
destroyNative();
|
||||||
|
} finally {
|
||||||
|
mLock.writeLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -174,14 +208,64 @@ public final class BluetoothSocket implements Closeable {
|
|||||||
return mOutputStream;
|
return mOutputStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*package*/ void bindListen() throws IOException {
|
||||||
|
mLock.readLock().lock();
|
||||||
|
try {
|
||||||
|
if (mClosed) throw new IOException("socket closed");
|
||||||
|
bindListenNative();
|
||||||
|
} finally {
|
||||||
|
mLock.readLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*package*/ BluetoothSocket accept(int timeout) throws IOException {
|
||||||
|
mLock.readLock().lock();
|
||||||
|
try {
|
||||||
|
if (mClosed) throw new IOException("socket closed");
|
||||||
|
return acceptNative(timeout);
|
||||||
|
} finally {
|
||||||
|
mLock.readLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*package*/ int available() throws IOException {
|
||||||
|
mLock.readLock().lock();
|
||||||
|
try {
|
||||||
|
if (mClosed) throw new IOException("socket closed");
|
||||||
|
return availableNative();
|
||||||
|
} finally {
|
||||||
|
mLock.readLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*package*/ int read(byte[] b, int offset, int length) throws IOException {
|
||||||
|
mLock.readLock().lock();
|
||||||
|
try {
|
||||||
|
if (mClosed) throw new IOException("socket closed");
|
||||||
|
return readNative(b, offset, length);
|
||||||
|
} finally {
|
||||||
|
mLock.readLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*package*/ int write(byte[] b, int offset, int length) throws IOException {
|
||||||
|
mLock.readLock().lock();
|
||||||
|
try {
|
||||||
|
if (mClosed) throw new IOException("socket closed");
|
||||||
|
return writeNative(b, offset, length);
|
||||||
|
} finally {
|
||||||
|
mLock.readLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private native void initSocketNative() throws IOException;
|
private native void initSocketNative() throws IOException;
|
||||||
private native void initSocketFromFdNative(int fd) throws IOException;
|
private native void initSocketFromFdNative(int fd) throws IOException;
|
||||||
private native void connectNative() throws IOException;
|
private native void connectNative() throws IOException;
|
||||||
/*package*/ native void bindListenNative() throws IOException;
|
private native void bindListenNative() throws IOException;
|
||||||
/*package*/ native BluetoothSocket acceptNative(int timeout) throws IOException;
|
private native BluetoothSocket acceptNative(int timeout) throws IOException;
|
||||||
/*package*/ native int availableNative() throws IOException;
|
private native int availableNative() throws IOException;
|
||||||
/*package*/ native int readNative(byte[] b, int offset, int length) throws IOException;
|
private native int readNative(byte[] b, int offset, int length) throws IOException;
|
||||||
/*package*/ native int writeNative(byte[] b, int offset, int length) throws IOException;
|
private native int writeNative(byte[] b, int offset, int length) throws IOException;
|
||||||
/*package*/ native void closeNative() throws IOException;
|
private native void abortNative() throws IOException;
|
||||||
private native void destroyNative() throws IOException;
|
private native void destroyNative() throws IOException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -468,7 +468,7 @@ static jint writeNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void closeNative(JNIEnv *env, jobject obj) {
|
static void abortNative(JNIEnv *env, jobject obj) {
|
||||||
#ifdef HAVE_BLUETOOTH
|
#ifdef HAVE_BLUETOOTH
|
||||||
LOGV(__FUNCTION__);
|
LOGV(__FUNCTION__);
|
||||||
struct asocket *s = get_socketData(env, obj);
|
struct asocket *s = get_socketData(env, obj);
|
||||||
@@ -510,7 +510,7 @@ static JNINativeMethod sMethods[] = {
|
|||||||
{"availableNative", "()I", (void *) availableNative},
|
{"availableNative", "()I", (void *) availableNative},
|
||||||
{"readNative", "([BII)I", (void *) readNative},
|
{"readNative", "([BII)I", (void *) readNative},
|
||||||
{"writeNative", "([BII)I", (void *) writeNative},
|
{"writeNative", "([BII)I", (void *) writeNative},
|
||||||
{"closeNative", "()V", (void *) closeNative},
|
{"abortNative", "()V", (void *) abortNative},
|
||||||
{"destroyNative", "()V", (void *) destroyNative},
|
{"destroyNative", "()V", (void *) destroyNative},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user