Skip to content

Commit 8682fb7

Browse files
authored
Rename handles and timeouts, add timeouts to 'shell' and 'root' (#103)
* Rename files: 'handle' -> 'transport' * Use sed to replace 'handle' with 'transport' * Rename the *Handle classes * Rebuild documentation * 'InvalidHandleError' -> 'InvalidTransportError' * 'PATCH_TCP_HANDLE' -> 'PATCH_TCP_TRANSPORT' * Rename 'timeout_s' -> 'transport_timeout_s' and 'default_timeout_s' -> 'default_transport_timeout_s' * Alphabetize attributes * Documentation * 'total_timeout_s' -> 'read_timeout_s' * 'DEFAULT_TOTAL_TIMEOUT_S' -> 'DEFAULT_READ_TIMEOUT_S' * Alphabetize attributes * Working on a better timeout * String formatting * Change 'setblocking(0)' to 'setblocking(False)' * Add a timeout for shell commands * Fail async tests when a warning is raised * Add 'async_patch' function * Renaming, documentation, and cleanup * Text alignment * Documentation * 'transportd' -> 'handled'
1 parent 7185080 commit 8682fb7

38 files changed

+1086
-983
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ install:
1515
- pip install flake8 pylint coveralls cryptography libusb1>=1.0.16 pycryptodome
1616
- python --version 2>&1 | grep -q "Python 2" && pip install mock || true
1717
script:
18-
- if python --version 2>&1 | grep -q "Python 2" || python --version 2>&1 | grep -q "Python 3.5"; then flake8 adb_shell/ --exclude="adb_shell/adb_device_async.py,adb_shell/handle/base_handle_async.py,adb_shell/handle/tcp_handle_async.py" && pylint --ignore="adb_device_async.py,base_handle_async.py,tcp_handle_async.py" adb_shell/; fi
18+
- if python --version 2>&1 | grep -q "Python 2" || python --version 2>&1 | grep -q "Python 3.5"; then flake8 adb_shell/ --exclude="adb_shell/adb_device_async.py,adb_shell/transport/base_transport_async.py,adb_shell/transport/tcp_transport_async.py" && pylint --ignore="adb_device_async.py,base_transport_async.py,tcp_transport_async.py" adb_shell/; fi
1919
- if python --version 2>&1 | grep -q "Python 3.6" || python --version 2>&1 | grep -q "Python 3.7" || python --version 2>&1 | grep -q "Python 3.8"; then flake8 adb_shell/ && pylint adb_shell/; fi
2020
- if python --version 2>&1 | grep -q "Python 2" || python --version 2>&1 | grep -q "Python 3.5"; then for synctest in $(cd tests && ls test*.py | grep -v async); do python -m unittest discover -s tests/ -t . -p "$synctest" || exit 1; done; fi
2121
- if python --version 2>&1 | grep -q "Python 3.6" || python --version 2>&1 | grep -q "Python 3.7" || python --version 2>&1 | grep -q "Python 3.8"; then coverage run --source adb_shell -m unittest discover -s tests/ -t . && coverage report -m; fi

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ tdd:
2828

2929
.PHONY: lint
3030
lint:
31-
python --version 2>&1 | grep -q "Python 2" && (flake8 adb_shell/ --exclude="adb_shell/adb_device_async.py,adb_shell/handle/base_handle_async.py,adb_shell/handle/tcp_handle_async.py" && pylint --ignore="adb_device_async.py,base_handle_async.py,tcp_handle_async.py" adb_shell/) || (flake8 adb_shell/ && pylint adb_shell/)
31+
python --version 2>&1 | grep -q "Python 2" && (flake8 adb_shell/ --exclude="adb_shell/adb_device_async.py,adb_shell/transport/base_transport_async.py,adb_shell/transport/tcp_transport_async.py" && pylint --ignore="adb_device_async.py,base_transport_async.py,tcp_transport_async.py" adb_shell/) || (flake8 adb_shell/ && pylint adb_shell/)
3232

3333
.PHONY: alltests
3434
alltests:

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ Example Usage
4747
from adb_shell.auth.sign_pythonrsa import PythonRSASigner
4848
4949
# Connect (no authentication necessary)
50-
device1 = AdbDeviceTcp('192.168.0.111', 5555, default_timeout_s=9.)
50+
device1 = AdbDeviceTcp('192.168.0.111', 5555, default_transport_timeout_s=9.)
5151
device1.connect(auth_timeout_s=0.1)
5252
5353
# Connect (authentication required)
5454
with open('path/to/adbkey') as f:
5555
priv = f.read()
5656
signer = PythonRSASigner('', priv)
57-
device2 = AdbDeviceTcp('192.168.0.222', 5555, default_timeout_s=9.)
57+
device2 = AdbDeviceTcp('192.168.0.222', 5555, default_transport_timeout_s=9.)
5858
device2.connect(rsa_keys=[signer], auth_timeout_s=0.1)
5959
6060
# Connect via USB (package must be installed via `pip install adb-shell[usb])`

adb_shell/adb_device.py

Lines changed: 116 additions & 104 deletions
Large diffs are not rendered by default.

adb_shell/adb_device_async.py

Lines changed: 105 additions & 93 deletions
Large diffs are not rendered by default.

adb_shell/adb_message.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def unpack(message):
8888
arg1 : int
8989
TODO
9090
data_length : int
91-
The length of the data sent by the device (used by :meth:`adb_shell.adb_device._read`)
91+
The length of the data sent by the device (used by :meth:`adb_shell.adb_device.AdbDevice._read` and :meth:`adb_shell.adb_device_async.AdbDeviceAsync._read`)
9292
data_checksum : int
9393
The checksum of the data sent by the device
9494
@@ -114,18 +114,18 @@ class AdbMessage(object):
114114
command : bytes
115115
A command; examples used in this package include :const:`adb_shell.constants.AUTH`, :const:`adb_shell.constants.CNXN`, :const:`adb_shell.constants.CLSE`, :const:`adb_shell.constants.OPEN`, and :const:`adb_shell.constants.OKAY`
116116
arg0 : int
117-
Usually the local ID, but :meth:`~adb_shell.adb_device.AdbDevice.connect` provides :const:`adb_shell.constants.VERSION`, :const:`adb_shell.constants.AUTH_SIGNATURE`, and :const:`adb_shell.constants.AUTH_RSAPUBLICKEY`
117+
Usually the local ID, but :meth:`~adb_shell.adb_device.AdbDevice.connect` and :meth:`~adb_shell.adb_device_async.AdbDeviceAsync.connect` provide :const:`adb_shell.constants.VERSION`, :const:`adb_shell.constants.AUTH_SIGNATURE`, and :const:`adb_shell.constants.AUTH_RSAPUBLICKEY`
118118
arg1 : int
119-
Usually the remote ID, but :meth:`~adb_shell.adb_device.AdbDevice.connect` provides :const:`adb_shell.constants.MAX_ADB_DATA`
119+
Usually the remote ID, but :meth:`~adb_shell.adb_device.AdbDevice.connect` and :meth:`~adb_shell.adb_device_async.AdbDeviceAsync.connect` provide :const:`adb_shell.constants.MAX_ADB_DATA`
120120
data : bytes
121121
The data that will be sent
122122
123123
Attributes
124124
----------
125125
arg0 : int
126-
Usually the local ID, but :meth:`~adb_shell.adb_device.AdbDevice.connect` provides :const:`adb_shell.constants.VERSION`, :const:`adb_shell.constants.AUTH_SIGNATURE`, and :const:`adb_shell.constants.AUTH_RSAPUBLICKEY`
126+
Usually the local ID, but :meth:`~adb_shell.adb_device.AdbDevice.connect` and :meth:`~adb_shell.adb_device_async.AdbDeviceAsync.connect` provide :const:`adb_shell.constants.VERSION`, :const:`adb_shell.constants.AUTH_SIGNATURE`, and :const:`adb_shell.constants.AUTH_RSAPUBLICKEY`
127127
arg1 : int
128-
Usually the remote ID, but :meth:`~adb_shell.adb_device.AdbDevice.connect` provides :const:`adb_shell.constants.MAX_ADB_DATA`
128+
Usually the remote ID, but :meth:`~adb_shell.adb_device.AdbDevice.connect` and :meth:`~adb_shell.adb_device_async.AdbDeviceAsync.connect` provide :const:`adb_shell.constants.MAX_ADB_DATA`
129129
command : int
130130
The input parameter ``command`` converted to an integer via :const:`adb_shell.constants.ID_TO_WIRE`
131131
data : bytes

adb_shell/constants.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
SEND = b'SEND'
7676
STAT = b'STAT'
7777

78-
#: Commands that are recognized by :meth:`adb_shell.adb_device.AdbDevice._read`
78+
#: Commands that are recognized by :meth:`adb_shell.adb_device.AdbDevice._read` and :meth:`adb_shell.adb_device_async.AdbDeviceAsync._read`
7979
IDS = (AUTH, CLSE, CNXN, OKAY, OPEN, SYNC, WRTE)
8080

8181
#: A dictionary where the keys are the commands in :const:`IDS` and the values are the keys converted to integers
@@ -84,7 +84,7 @@
8484
#: A dictionary where the keys are integers and the values are their corresponding commands (type = bytes) from :const:`IDS`
8585
WIRE_TO_ID = {wire: cmd_id for cmd_id, wire in ID_TO_WIRE.items()}
8686

87-
#: Commands that are recognized by :meth:`adb_shell.adb_device.AdbDevice._filesync_read`
87+
#: Commands that are recognized by :meth:`adb_shell.adb_device.AdbDevice._filesync_read` and :meth:`adb_shell.adb_device_async.AdbDeviceAsync._filesync_read`
8888
FILESYNC_IDS = (DATA, DENT, DONE, FAIL, LIST, OKAY, QUIT, RECV, SEND, STAT)
8989

9090
#: A dictionary where the keys are the commands in :const:`FILESYNC_IDS` and the values are the keys converted to integers
@@ -111,8 +111,8 @@
111111
#: The size of an ADB message
112112
MESSAGE_SIZE = struct.calcsize(MESSAGE_FORMAT)
113113

114-
#: Default authentication timeout (in s) for :meth:`adb_shell.tcp_handle.TcpHandle.connect`
114+
#: Default authentication timeout (in s) for :meth:`adb_shell.adb_device.AdbDevice.connect` and :meth:`adb_shell.adb_device_async.AdbDeviceAsync.connect`
115115
DEFAULT_AUTH_TIMEOUT_S = 10.
116116

117-
#: Default total timeout (in s) for :meth:`adb_shell.adb_device.AdbDevice._read`
118-
DEFAULT_TOTAL_TIMEOUT_S = 10.
117+
#: Default total timeout (in s) for :meth:`adb_shell.adb_device.AdbDevice._read`, :meth:`adb_shell.adb_device.AdbDevice._read_until`, :meth:`adb_shell.adb_device_async.AdbDeviceAsync._read`, and :meth:`adb_shell.adb_device_async.AdbDeviceAsync._read_until`
118+
DEFAULT_READ_TIMEOUT_S = 10.

adb_shell/exceptions.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ class AdbConnectionError(Exception):
3838
"""
3939

4040

41+
class AdbTimeoutError(Exception):
42+
"""ADB command did not complete within the specified time.
43+
44+
"""
45+
46+
4147
class DeviceAuthError(Exception):
4248
"""Device authentication failed.
4349
@@ -69,8 +75,8 @@ def __init__(self, message, response_header, response_data):
6975
super(InvalidCommandError, self).__init__(message, response_header, response_data)
7076

7177

72-
class InvalidHandleError(Exception):
73-
"""The provided handle does not implement the necessary methods: ``close``, ``connect``, ``bulk_read``, and ``bulk_write``.
78+
class InvalidTransportError(Exception):
79+
"""The provided transport does not implement the necessary methods: ``close``, ``connect``, ``bulk_read``, and ``bulk_write``.
7480
7581
"""
7682

@@ -124,6 +130,6 @@ def __str__(self):
124130

125131

126132
class UsbWriteFailedError(Exception):
127-
""":meth:`adb_shell.handle.usb_handle.UsbHandle.bulk_write` failed.
133+
""":meth:`adb_shell.transport.usb_transport.UsbTransport.bulk_write` failed.
128134
129135
"""

adb_shell/hidden_helpers.py

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,36 +81,54 @@ def _open(name, mode='r'):
8181
class _AdbTransactionInfo(object): # pylint: disable=too-few-public-methods
8282
"""A class for storing info and settings used during a single ADB "transaction."
8383
84+
Note that if ``timeout_s`` is not ``None``, then:
85+
86+
::
87+
88+
self.transport_timeout_s <= self.read_timeout_s <= self.timeout_s
89+
90+
If ``timeout_s`` is ``None``, the first inequality still applies.
91+
92+
8493
Parameters
8594
----------
8695
local_id : int
8796
The ID for the sender (i.e., the device running this code)
8897
remote_id : int
8998
The ID for the recipient
99+
transport_timeout_s : float, None
100+
Timeout in seconds for sending and receiving packets, or ``None``; see :meth:`BaseTransport.bulk_read() <adb_shell.transport.base_transport.BaseTransport.bulk_read>`,
101+
:meth:`BaseTransport.bulk_write() <adb_shell.transport.base_transport.BaseTransport.bulk_write>`,
102+
:meth:`BaseTransportAsync.bulk_read() <adb_shell.transport.base_transport_async.BaseTransportAsync.bulk_read>`, and
103+
:meth:`BaseTransportAsync.bulk_write() <adb_shell.transport.base_transport_async.BaseTransportAsync.bulk_write>`
104+
read_timeout_s : float
105+
The total time in seconds to wait for a command in ``expected_cmds`` in :meth:`AdbDevice._read` and :meth:`AdbDeviceAsync._read`
90106
timeout_s : float, None
91-
Timeout in seconds for sending and receiving packets, or ``None``; see :meth:`BaseHandle.bulk_read() <adb_shell.handle.base_handle.BaseHandle.bulk_read>`
92-
and :meth:`BaseHandle.bulk_write() <adb_shell.handle.base_handle.BaseHandle.bulk_write>`
93-
total_timeout_s : float
94-
The total time in seconds to wait for a command in ``expected_cmds`` in :meth:`AdbDevice._read`
107+
The total time in seconds to wait for the ADB command to finish
95108
96109
Attributes
97110
----------
98111
local_id : int
99112
The ID for the sender (i.e., the device running this code)
113+
read_timeout_s : float
114+
The total time in seconds to wait for a command in ``expected_cmds`` in :meth:`AdbDevice._read` and :meth:`AdbDeviceAsync._read`
100115
remote_id : int
101116
The ID for the recipient
102117
timeout_s : float, None
103-
Timeout in seconds for sending and receiving packets, or ``None``; see :meth:`BaseHandle.bulk_read() <adb_shell.handle.base_handle.BaseHandle.bulk_read>`
104-
and :meth:`BaseHandle.bulk_write() <adb_shell.handle.base_handle.BaseHandle.bulk_write>`
105-
total_timeout_s : float
106-
The total time in seconds to wait for a command in ``expected_cmds`` in :meth:`AdbDevice._read`
118+
The total time in seconds to wait for the ADB command to finish
119+
transport_timeout_s : float, None
120+
Timeout in seconds for sending and receiving packets, or ``None``; see :meth:`BaseTransport.bulk_read() <adb_shell.transport.base_transport.BaseTransport.bulk_read>`,
121+
:meth:`BaseTransport.bulk_write() <adb_shell.transport.base_transport.BaseTransport.bulk_write>`,
122+
:meth:`BaseTransportAsync.bulk_read() <adb_shell.transport.base_transport_async.BaseTransportAsync.bulk_read>`, and
123+
:meth:`BaseTransportAsync.bulk_write() <adb_shell.transport.base_transport_async.BaseTransportAsync.bulk_write>`
107124
108125
"""
109-
def __init__(self, local_id, remote_id, timeout_s=None, total_timeout_s=constants.DEFAULT_TOTAL_TIMEOUT_S):
126+
def __init__(self, local_id, remote_id, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, timeout_s=None):
110127
self.local_id = local_id
111128
self.remote_id = remote_id
112129
self.timeout_s = timeout_s
113-
self.total_timeout_s = total_timeout_s
130+
self.read_timeout_s = read_timeout_s if self.timeout_s is None else min(read_timeout_s, self.timeout_s)
131+
self.transport_timeout_s = self.read_timeout_s if transport_timeout_s is None else min(transport_timeout_s, self.read_timeout_s)
114132

115133

116134
class _FileSyncTransactionInfo(object): # pylint: disable=too-few-public-methods

0 commit comments

Comments
 (0)