summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/bluetooth/BluetoothOutputStream.java11
-rw-r--r--core/java/android/bluetooth/BluetoothSocket.java12
-rw-r--r--core/java/android/net/LocalSocketImpl.java20
-rw-r--r--core/jni/android_net_LocalSocketImpl.cpp25
4 files changed, 68 insertions, 0 deletions
diff --git a/core/java/android/bluetooth/BluetoothOutputStream.java b/core/java/android/bluetooth/BluetoothOutputStream.java
index 62242a2..117dd47 100644
--- a/core/java/android/bluetooth/BluetoothOutputStream.java
+++ b/core/java/android/bluetooth/BluetoothOutputStream.java
@@ -84,4 +84,15 @@ import java.io.OutputStream;
}
mSocket.write(b, offset, count);
}
+ /**
+ * Wait until the data in sending queue is emptied. A polling version
+ * for flush implementation. Use it to ensure the writing data afterwards will
+ * be packed in the new RFCOMM frame.
+ * @throws IOException
+ * if an i/o error occurs.
+ * @since Android 4.2.3
+ */
+ public void flush() throws IOException {
+ mSocket.flush();
+ }
}
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index 8029a1a..a19341c 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -192,6 +192,7 @@ public final class BluetoothSocket implements Closeable {
if (VDBG) Log.d(TAG, "socket fd passed by stack fds: " + fds);
if(fds == null || fds.length != 1) {
Log.e(TAG, "socket fd passed from stack failed, fds: " + fds);
+ as.close();
throw new IOException("bt socket acept failed");
}
as.mSocket = new LocalSocket(fds[0]);
@@ -407,6 +408,17 @@ public final class BluetoothSocket implements Closeable {
if (VDBG) Log.d(TAG, "available: " + mSocketIS);
return mSocketIS.available();
}
+ /**
+ * Wait until the data in sending queue is emptied. A polling version
+ * for flush implementation. Used to ensure the writing data afterwards will
+ * be packed in new RFCOMM frame.
+ * @throws IOException
+ * if an i/o error occurs.
+ */
+ /*package*/ void flush() throws IOException {
+ if (VDBG) Log.d(TAG, "flush: " + mSocketOS);
+ mSocketOS.flush();
+ }
/*package*/ int read(byte[] b, int offset, int length) throws IOException {
diff --git a/core/java/android/net/LocalSocketImpl.java b/core/java/android/net/LocalSocketImpl.java
index 6c36a7d..8e129cb 100644
--- a/core/java/android/net/LocalSocketImpl.java
+++ b/core/java/android/net/LocalSocketImpl.java
@@ -136,8 +136,28 @@ class LocalSocketImpl
write_native(b, myFd);
}
}
+
+ /**
+ * Wait until the data in sending queue is emptied. A polling version
+ * for flush implementation.
+ * @throws IOException
+ * if an i/o error occurs.
+ */
+ @Override
+ public void flush() throws IOException {
+ FileDescriptor myFd = fd;
+ if (myFd == null) throw new IOException("socket closed");
+ while(pending_native(fd) > 0) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException ie) {
+ return;
+ }
+ }
+ }
}
+ private native int pending_native(FileDescriptor fd) throws IOException;
private native int available_native(FileDescriptor fd) throws IOException;
private native void close_native(FileDescriptor fd) throws IOException;
private native int read_native(FileDescriptor fd) throws IOException;
diff --git a/core/jni/android_net_LocalSocketImpl.cpp b/core/jni/android_net_LocalSocketImpl.cpp
index 1426b2c..f2b69c6 100644
--- a/core/jni/android_net_LocalSocketImpl.cpp
+++ b/core/jni/android_net_LocalSocketImpl.cpp
@@ -371,7 +371,31 @@ static void socket_setOption(
return;
}
}
+static jint socket_pending (JNIEnv *env, jobject object,
+ jobject fileDescriptor)
+{
+ int fd;
+
+ fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ if (env->ExceptionOccurred() != NULL) {
+ return (jint)-1;
+ }
+
+ int pending;
+ int ret = ioctl(fd, TIOCOUTQ, &pending);
+ // If this were a non-socket fd, there would be other cases to worry
+ // about...
+
+ //ALOGD("socket_pending, ioctl ret:%d, pending:%d", ret, pending);
+ if (ret < 0) {
+ jniThrowIOException(env, errno);
+ return (jint) 0;
+ }
+
+ return (jint)pending;
+}
static jint socket_available (JNIEnv *env, jobject object,
jobject fileDescriptor)
{
@@ -893,6 +917,7 @@ static JNINativeMethod gMethods[] = {
{"accept", "(Ljava/io/FileDescriptor;Landroid/net/LocalSocketImpl;)Ljava/io/FileDescriptor;", (void*)socket_accept},
{"shutdown", "(Ljava/io/FileDescriptor;Z)V", (void*)socket_shutdown},
{"available_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_available},
+ {"pending_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_pending},
{"close_native", "(Ljava/io/FileDescriptor;)V", (void*) socket_close},
{"read_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_read},
{"readba_native", "([BIILjava/io/FileDescriptor;)I", (void*) socket_readba},