summaryrefslogtreecommitdiffstats
path: root/core/java/android/bluetooth
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/bluetooth')
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java6
-rw-r--r--core/java/android/bluetooth/BluetoothInputStream.java6
-rw-r--r--core/java/android/bluetooth/BluetoothOutputStream.java4
-rw-r--r--core/java/android/bluetooth/BluetoothServerSocket.java5
-rw-r--r--core/java/android/bluetooth/BluetoothSocket.java102
5 files changed, 104 insertions, 19 deletions
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 6bd2a5a..8975fe2 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -312,7 +312,7 @@ public final class BluetoothAdapter {
BluetoothServerSocket socket = new BluetoothServerSocket(
BluetoothSocket.TYPE_RFCOMM, true, true, channel);
try {
- socket.mSocket.bindListenNative();
+ socket.mSocket.bindListen();
} catch (IOException e) {
try {
socket.close();
@@ -334,7 +334,7 @@ public final class BluetoothAdapter {
BluetoothServerSocket socket = new BluetoothServerSocket(
BluetoothSocket.TYPE_RFCOMM, false, false, port);
try {
- socket.mSocket.bindListenNative();
+ socket.mSocket.bindListen();
} catch (IOException e) {
try {
socket.close();
@@ -356,7 +356,7 @@ public final class BluetoothAdapter {
BluetoothServerSocket socket = new BluetoothServerSocket(
BluetoothSocket.TYPE_SCO, false, false, -1);
try {
- socket.mSocket.bindListenNative();
+ socket.mSocket.bindListen();
} catch (IOException e) {
try {
socket.close();
diff --git a/core/java/android/bluetooth/BluetoothInputStream.java b/core/java/android/bluetooth/BluetoothInputStream.java
index c060f32..03af953 100644
--- a/core/java/android/bluetooth/BluetoothInputStream.java
+++ b/core/java/android/bluetooth/BluetoothInputStream.java
@@ -37,7 +37,7 @@ import java.io.InputStream;
* Return number of bytes available before this stream will block.
*/
public int available() throws IOException {
- return mSocket.availableNative();
+ return mSocket.available();
}
public void close() throws IOException {
@@ -57,7 +57,7 @@ import java.io.InputStream;
*/
public int read() throws IOException {
byte b[] = new byte[1];
- int ret = mSocket.readNative(b, 0, 1);
+ int ret = mSocket.read(b, 0, 1);
if (ret == 1) {
return (int)b[0] & 0xff;
} else {
@@ -93,6 +93,6 @@ import java.io.InputStream;
if ((offset | length) < 0 || length > b.length - offset) {
throw new ArrayIndexOutOfBoundsException("invalid offset or length");
}
- return mSocket.readNative(b, offset, length);
+ return mSocket.read(b, offset, length);
}
}
diff --git a/core/java/android/bluetooth/BluetoothOutputStream.java b/core/java/android/bluetooth/BluetoothOutputStream.java
index 7e2ead4..62242a2 100644
--- a/core/java/android/bluetooth/BluetoothOutputStream.java
+++ b/core/java/android/bluetooth/BluetoothOutputStream.java
@@ -53,7 +53,7 @@ import java.io.OutputStream;
public void write(int oneByte) throws IOException {
byte b[] = new byte[1];
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) {
throw new IndexOutOfBoundsException("invalid offset or length");
}
- mSocket.writeNative(b, offset, count);
+ mSocket.write(b, offset, count);
}
}
diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java
index e653c23..b650841 100644
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ b/core/java/android/bluetooth/BluetoothServerSocket.java
@@ -47,6 +47,7 @@ import java.io.IOException;
* operations and close the socket.
*/
public final class BluetoothServerSocket implements Closeable {
+
/*package*/ final BluetoothSocket mSocket;
/**
@@ -88,7 +89,7 @@ public final class BluetoothServerSocket implements Closeable {
* timeout
*/
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.
*/
public void close() throws IOException {
- mSocket.closeNative();
+ mSocket.close();
}
}
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index eae0f37..ccbe23e 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -21,6 +21,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
/**
* A connected or connecting Bluetooth socket.
*
@@ -63,7 +65,14 @@ public final class BluetoothSocket implements Closeable {
private final BluetoothInputStream mInputStream;
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.
@@ -95,6 +104,8 @@ public final class BluetoothSocket implements Closeable {
}
mInputStream = new BluetoothInputStream(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
*/
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.
*/
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;
}
+ /*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 initSocketFromFdNative(int fd) throws IOException;
private native void connectNative() throws IOException;
- /*package*/ native void bindListenNative() throws IOException;
- /*package*/ native BluetoothSocket acceptNative(int timeout) throws IOException;
- /*package*/ native int availableNative() throws IOException;
- /*package*/ native int readNative(byte[] b, int offset, int length) throws IOException;
- /*package*/ native int writeNative(byte[] b, int offset, int length) throws IOException;
- /*package*/ native void closeNative() throws IOException;
+ private native void bindListenNative() throws IOException;
+ private native BluetoothSocket acceptNative(int timeout) throws IOException;
+ private native int availableNative() throws IOException;
+ private native int readNative(byte[] b, int offset, int length) throws IOException;
+ private native int writeNative(byte[] b, int offset, int length) throws IOException;
+ private native void abortNative() throws IOException;
private native void destroyNative() throws IOException;
}