diff --git a/adb/adb_commands.py b/adb/adb_commands.py index 8a745ba..91b9aac 100644 --- a/adb/adb_commands.py +++ b/adb/adb_commands.py @@ -68,7 +68,7 @@ def ConnectDevice( used instead of a USB connection. """ if serial and b':' in serial: - handle = common.TcpHandle(serial) + handle = common.TcpHandle(serial,timeout_ms=default_timeout_ms) else: handle = common.UsbHandle.FindAndOpen( DeviceIsAvailable, port_path=port_path, serial=serial, diff --git a/adb/common.py b/adb/common.py index e63fa00..e1acd7e 100644 --- a/adb/common.py +++ b/adb/common.py @@ -19,6 +19,7 @@ import socket import threading import weakref +import select import libusb1 import usb1 @@ -278,9 +279,9 @@ def FindDevices(cls, setting_matcher, device_matcher=None, class TcpHandle(object): """TCP connection object. - Provides same interface as UsbHandle but ignores timeout.""" + Provides same interface as UsbHandle. """ - def __init__(self, serial): + def __init__(self, serial, timeout_ms=None): """Initialize the TCP Handle. Arguments: serial: Android device serial of the form host or host:port. @@ -292,9 +293,12 @@ def __init__(self, serial): else: host = serial port = 5555 + self._timeout_ms = timeout_ms self._serial_number = '%s:%s' % (host, port) + timeout = self._timeout_ms/1000.0 if self._timeout_ms else None + self._connection = socket.create_connection((host,port),timeout=timeout) - self._connection = socket.create_connection((host, port)) + self._connection.setblocking(0) @property def serial_number(self): @@ -303,11 +307,16 @@ def serial_number(self): def BulkWrite(self, data, timeout=None): return self._connection.sendall(data) - def BulkRead(self, numbytes, timeout=None): - return self._connection.recv(numbytes) + def BulkRead(self, numbytes, timeout_ms=None): + t = self.Timeout(timeout_ms)/1000.0 if self.Timeout(timeout_ms) else None + ready = select.select([self._connection], [], [], t) + if ready[0]: + return self._connection.recv(numbytes) + msg = 'Reading from {} timed out (Timeout {}s)'.format(self._serial_number,t) + raise usb_exceptions.TCPTimeoutException(msg) def Timeout(self, timeout_ms): - return timeout_ms + return timeout_ms if timeout_ms is not None else self._timeout_ms def Close(self): return self._connection.close() diff --git a/adb/usb_exceptions.py b/adb/usb_exceptions.py index 4c50f53..aa02bac 100644 --- a/adb/usb_exceptions.py +++ b/adb/usb_exceptions.py @@ -70,3 +70,7 @@ class AdbCommandFailureException(Exception): class AdbOperationException(Exception): """Failed to communicate over adb with device after multiple retries.""" + + +class TCPTimeoutException(FormatMessageWithArgumentsException): + """TCP connection timed out in the time out given."""