Skip to content

Commit 825294d

Browse files
authored
Add AdbDevice._streaming_service and AdbDevice.streaming_shell (#80)
* Add AdbDevice._streaming_service and AdbDevice.streaming_shell streaming shell can be necessary for shell commands like "getevent -lt" * Add AdbDevice._streaming_service and AdbDevice.streaming_shell fix for python 2.7 * Add AdbDevice._streaming_service and AdbDevice.streaming_shell PR comments + unit tests * Add AdbDevice._streaming_service and AdbDevice.streaming_shell PR comments
1 parent da9ffba commit 825294d

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

adb_shell/adb_device.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
* :meth:`AdbDevice._send`
4747
* :meth:`AdbDevice._service`
4848
* :meth:`AdbDevice._streaming_command`
49+
* :meth:`AdbDevice._streaming_service`
4950
* :meth:`AdbDevice._write`
5051
* :attr:`AdbDevice.available`
5152
* :meth:`AdbDevice.close`
@@ -55,6 +56,7 @@
5556
* :meth:`AdbDevice.push`
5657
* :meth:`AdbDevice.shell`
5758
* :meth:`AdbDevice.stat`
59+
* :meth:`AdbDevice.streaming_shell`
5860
5961
* :class:`AdbDeviceTcp`
6062
@@ -402,6 +404,38 @@ def _service(self, service, command, timeout_s=None, total_timeout_s=constants.D
402404
return b''.join(self._streaming_command(service, command, adb_info)).decode('utf8')
403405
return b''.join(self._streaming_command(service, command, adb_info))
404406

407+
def _streaming_service(self, service, command, timeout_s=None, total_timeout_s=constants.DEFAULT_TOTAL_TIMEOUT_S, decode=True):
408+
"""Send an ADB command to the device, yielding each line of output.
409+
410+
Parameters
411+
----------
412+
service : bytes
413+
The ADB service to talk to (e.g., ``b'shell'``)
414+
command : bytes
415+
The command that will be sent
416+
timeout_s : float, None
417+
Timeout in seconds for sending and receiving packets, or ``None``; see :meth:`BaseHandle.bulk_read() <adb_shell.handle.base_handle.BaseHandle.bulk_read>`
418+
and :meth:`BaseHandle.bulk_write() <adb_shell.handle.base_handle.BaseHandle.bulk_write>`
419+
total_timeout_s : float
420+
The total time in seconds to wait for a ``b'CLSE'`` or ``b'OKAY'`` command in :meth:`AdbDevice._read`
421+
decode : bool
422+
Whether to decode the output to utf8 before returning
423+
424+
Yields
425+
-------
426+
bytes, str
427+
The line-by-line output of the ADB command as a string if ``decode`` is True, otherwise as bytes.
428+
429+
"""
430+
adb_info = _AdbTransactionInfo(None, None, timeout_s, total_timeout_s)
431+
stream = self._streaming_command(service, command, adb_info)
432+
if decode:
433+
for line in (stream_line.decode('utf8') for stream_line in stream):
434+
yield line
435+
else:
436+
for line in stream:
437+
yield line
438+
405439
def shell(self, command, timeout_s=None, total_timeout_s=constants.DEFAULT_TOTAL_TIMEOUT_S, decode=True):
406440
"""Send an ADB shell command to the device.
407441
@@ -425,6 +459,30 @@ def shell(self, command, timeout_s=None, total_timeout_s=constants.DEFAULT_TOTAL
425459
"""
426460
return self._service(b'shell', command.encode('utf8'), timeout_s, total_timeout_s, decode)
427461

462+
def streaming_shell(self, command, timeout_s=None, total_timeout_s=constants.DEFAULT_TOTAL_TIMEOUT_S, decode=True):
463+
"""Send an ADB shell command to the device, yielding each line of output.
464+
465+
Parameters
466+
----------
467+
command : str
468+
The shell command that will be sent
469+
timeout_s : float, None
470+
Timeout in seconds for sending and receiving packets, or ``None``; see :meth:`BaseHandle.bulk_read() <adb_shell.handle.base_handle.BaseHandle.bulk_read>`
471+
and :meth:`BaseHandle.bulk_write() <adb_shell.handle.base_handle.BaseHandle.bulk_write>`
472+
total_timeout_s : float
473+
The total time in seconds to wait for a ``b'CLSE'`` or ``b'OKAY'`` command in :meth:`AdbDevice._read`
474+
decode : bool
475+
Whether to decode the output to utf8 before returning
476+
477+
Yields
478+
-------
479+
bytes, str
480+
The line-by-line output of the ADB shell command as a string if ``decode`` is True, otherwise as bytes.
481+
482+
"""
483+
for line in self._streaming_service(b'shell', command.encode('utf8'), timeout_s, total_timeout_s, decode):
484+
yield line
485+
428486
# ======================================================================= #
429487
# #
430488
# FileSync #

tests/test_adb_device.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,40 @@ def test_issue29(self):
397397
self.device.shell('Android TV update command')
398398
self.device.shell('Android TV update command')
399399

400+
# ======================================================================= #
401+
# #
402+
# `streaming_shell` tests #
403+
# #
404+
# ======================================================================= #
405+
def test_streaming_shell_decode(self):
406+
self.assertTrue(self.device.connect())
407+
408+
# Provide the `bulk_read` return values
409+
self.device._handle._bulk_read = join_messages(
410+
AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'),
411+
AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'ABC'),
412+
AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'123'),
413+
)
414+
415+
generator = self.device.streaming_shell('TEST', decode=True)
416+
self.assertEqual('ABC', next(generator))
417+
self.assertEqual('123', next(generator))
418+
419+
def test_streaming_shell_dont_decode(self):
420+
self.assertTrue(self.device.connect())
421+
422+
# Provide the `bulk_read` return values
423+
self.device._handle._bulk_read = join_messages(
424+
AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'),
425+
AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'ABC'),
426+
AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'123'),
427+
)
428+
429+
generator = self.device.streaming_shell('TEST', decode=False)
430+
self.assertEqual(b'ABC', next(generator))
431+
self.assertEqual(b'123', next(generator))
432+
433+
400434
# ======================================================================= #
401435
# #
402436
# `filesync` tests #

0 commit comments

Comments
 (0)