diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CommonUsbSerialPort.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CommonUsbSerialPort.java index a6414c9..3dc625d 100644 --- a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CommonUsbSerialPort.java +++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CommonUsbSerialPort.java @@ -12,6 +12,8 @@ import android.hardware.usb.UsbEndpoint; import android.hardware.usb.UsbRequest; import android.util.Log; +import com.hoho.android.usbserial.util.MonotonicClock; + import java.io.IOException; import java.nio.ByteBuffer; import java.util.EnumSet; @@ -178,11 +180,11 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort { // /system/lib64/libusbhost.so (usb_request_wait+192) // /system/lib64/libandroid_runtime.so (android_hardware_UsbDeviceConnection_request_wait(_JNIEnv*, _jobject*, long)+84) // data loss / crashes were observed with timeout up to 200 msec - long endTime = testConnection ? System.currentTimeMillis() + timeout : 0; + long endTime = testConnection ? MonotonicClock.millis() + timeout : 0; int readMax = Math.min(dest.length, MAX_READ_SIZE); nread = mConnection.bulkTransfer(mReadEndpoint, dest, readMax, timeout); // Android error propagation is improvable, nread == -1 can be: timeout, connection lost, buffer undersized, ... - if(nread == -1 && testConnection && System.currentTimeMillis() < endTime) + if(nread == -1 && testConnection && MonotonicClock.millis() < endTime) testConnection(); } else { @@ -205,7 +207,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort { @Override public void write(final byte[] src, final int timeout) throws IOException { int offset = 0; - final long endTime = (timeout == 0) ? 0 : (System.currentTimeMillis() + timeout); + final long endTime = (timeout == 0) ? 0 : (MonotonicClock.millis() + timeout); if(mConnection == null) { throw new IOException("Connection closed"); @@ -229,7 +231,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort { if (timeout == 0 || offset == 0) { requestTimeout = timeout; } else { - requestTimeout = (int)(endTime - System.currentTimeMillis()); + requestTimeout = (int)(endTime - MonotonicClock.millis()); if(requestTimeout == 0) requestTimeout = -1; } @@ -241,7 +243,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort { } Log.d(TAG, "Wrote " + actualLength + "/" + requestLength + " offset " + offset + "/" + src.length + " timeout " + requestTimeout); if (actualLength <= 0) { - if (timeout != 0 && System.currentTimeMillis() >= endTime) { + if (timeout != 0 && MonotonicClock.millis() >= endTime) { SerialTimeoutException ex = new SerialTimeoutException("Error writing " + requestLength + " bytes at offset " + offset + " of total " + src.length + ", rc=" + actualLength); ex.bytesTransferred = offset; throw ex; diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/FtdiSerialDriver.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/FtdiSerialDriver.java index 40281c2..14f4ec9 100644 --- a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/FtdiSerialDriver.java +++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/FtdiSerialDriver.java @@ -12,6 +12,8 @@ import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDeviceConnection; import android.util.Log; +import com.hoho.android.usbserial.util.MonotonicClock; + import java.io.IOException; import java.util.ArrayList; import java.util.EnumSet; @@ -146,11 +148,11 @@ public class FtdiSerialDriver implements UsbSerialDriver { } int nread; if (timeout != 0) { - long endTime = System.currentTimeMillis() + timeout; + long endTime = MonotonicClock.millis() + timeout; do { - nread = super.read(dest, Math.max(1, (int)(endTime - System.currentTimeMillis())), false); - } while (nread == READ_HEADER_LENGTH && System.currentTimeMillis() < endTime); - if(nread <= 0 && System.currentTimeMillis() < endTime) + nread = super.read(dest, Math.max(1, (int)(endTime - MonotonicClock.millis())), false); + } while (nread == READ_HEADER_LENGTH && MonotonicClock.millis() < endTime); + if(nread <= 0 && MonotonicClock.millis() < endTime) testConnection(); } else { do { diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProlificSerialDriver.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProlificSerialDriver.java index 2be6f61..60aab27 100644 --- a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProlificSerialDriver.java +++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProlificSerialDriver.java @@ -17,6 +17,7 @@ import android.hardware.usb.UsbInterface; import android.util.Log; import com.hoho.android.usbserial.BuildConfig; +import com.hoho.android.usbserial.util.MonotonicClock; import java.io.IOException; import java.util.Collections; @@ -174,9 +175,9 @@ public class ProlificSerialDriver implements UsbSerialDriver { try { while (!mStopReadStatusThread) { byte[] buffer = new byte[STATUS_BUFFER_SIZE]; - long endTime = System.currentTimeMillis() + 500; + long endTime = MonotonicClock.millis() + 500; int readBytesCount = mConnection.bulkTransfer(mInterruptEndpoint, buffer, STATUS_BUFFER_SIZE, 500); - if(readBytesCount == -1 && System.currentTimeMillis() < endTime) + if(readBytesCount == -1 && MonotonicClock.millis() < endTime) testConnection(); if (readBytesCount > 0) { if (readBytesCount != STATUS_BUFFER_SIZE) { diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/util/MonotonicClock.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/util/MonotonicClock.java new file mode 100644 index 0000000..befc3dc --- /dev/null +++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/util/MonotonicClock.java @@ -0,0 +1,14 @@ +package com.hoho.android.usbserial.util; + +public final class MonotonicClock { + + private static final long NS_PER_MS = 1_000_000; + + private MonotonicClock() { + } + + public static long millis() { + return System.nanoTime() / NS_PER_MS; + } + +}