OSDN Git Service

Added flush() for bluetooth output stream
authorzzy <zhenye@broadcom.com>
Wed, 17 Apr 2013 00:17:37 +0000 (17:17 -0700)
committerMatthew Xie <mattx@google.com>
Wed, 24 Apr 2013 07:24:34 +0000 (00:24 -0700)
Bug 8498784

Zebra QL420 Plus Bluetooth printer fails on Android 4.2.2

core/java/android/bluetooth/BluetoothOutputStream.java
core/java/android/bluetooth/BluetoothSocket.java
core/java/android/net/LocalSocketImpl.java
core/jni/android_net_LocalSocketImpl.cpp

index 62242a2..117dd47 100644 (file)
@@ -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();
+    }
 }
index 8029a1a..a19341c 100644 (file)
@@ -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 {
 
index 6c36a7d..8e129cb 100644 (file)
@@ -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;
index 1426b2c..f2b69c6 100644 (file)
@@ -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},