Skip to content

Commit

Permalink
Revert "Use async ADB server code from pure-python-adb (#193)"
Browse files Browse the repository at this point in the history
This reverts commit 52864be.
  • Loading branch information
JeffLIrion committed Sep 12, 2020
1 parent 9ab0e5b commit d081fd5
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 4 deletions.
43 changes: 41 additions & 2 deletions androidtv/adb_manager/adb_manager_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,50 @@
from adb_shell.adb_device_async import AdbDeviceTcpAsync
from adb_shell.auth.sign_pythonrsa import PythonRSASigner
import aiofiles
from ppadb.client_async import ClientAsync
from ppadb.client import Client

from ..constants import DEFAULT_ADB_TIMEOUT_S, DEFAULT_AUTH_TIMEOUT_S, DEFAULT_LOCK_TIMEOUT_S
from ..exceptions import LockNotAcquiredException

_LOGGER = logging.getLogger(__name__)


class DeviceAsync:
"""A fake ``DeviceAsync`` class."""
def __init__(self, device):
self._device = device

async def pull(self, device_path, local_path):
"""Download a file."""
return await asyncio.get_running_loop().run_in_executor(None, self._device.pull, device_path, local_path)

async def push(self, local_path, device_path):
"""Upload a file."""
return await asyncio.get_running_loop().run_in_executor(None, self._device.push, local_path, device_path)

async def screencap(self):
"""Take a screencap."""
return await asyncio.get_running_loop().run_in_executor(None, self._device.screencap)

async def shell(self, cmd):
"""Send a shell command."""
return await asyncio.get_running_loop().run_in_executor(None, self._device.shell, cmd)


# pylint: disable=too-few-public-methods
class ClientAsync:
"""A fake ``ClientAsync`` class."""
def __init__(self, host, port):
self._client = Client(host, port)

async def device(self, serial):
"""Get a fake ``DeviceAsync`` instance."""
dev = await asyncio.get_running_loop().run_in_executor(None, self._client.device, serial)
if dev:
return DeviceAsync(dev)
return None


@asynccontextmanager
async def _acquire(lock, timeout=DEFAULT_LOCK_TIMEOUT_S):
"""Handle acquisition and release of an ``asyncio.Lock`` object with a timeout.
Expand Down Expand Up @@ -440,7 +476,10 @@ async def screencap(self):

async with _acquire(self._adb_lock):
_LOGGER.debug("Taking screencap from %s:%d via ADB server %s:%d", self.host, self.port, self.adb_server_ip, self.adb_server_port)
return await self._adb_device.screencap()
try:
return await self._adb_device.screencap()
except IndexError:
return None

async def shell(self, cmd):
"""Send an ADB command using an ADB server.
Expand Down
5 changes: 4 additions & 1 deletion androidtv/adb_manager/adb_manager_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,10 @@ def screencap(self):

with _acquire(self._adb_lock):
_LOGGER.debug("Taking screencap from %s:%d via ADB server %s:%d", self.host, self.port, self.adb_server_ip, self.adb_server_port)
return self._adb_device.screencap()
try:
return self._adb_device.screencap()
except IndexError:
return None

def shell(self, cmd):
"""Send an ADB command using an ADB server.
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
author='Jeff Irion',
author_email='jefflirion@users.noreply.github.com',
packages=['androidtv', 'androidtv.adb_manager', 'androidtv.basetv', 'androidtv.androidtv', 'androidtv.firetv'],
install_requires=['adb-shell>=0.2.1', 'pure-python-adb>=0.3.0.dev0'],
install_requires=['adb-shell>=0.2.1', 'pure-python-adb>=0.2.2.dev0'],
extras_require={'async': ['aiofiles>=0.4.0']},
classifiers=[
'License :: OSI Approved :: MIT License',
Expand Down
2 changes: 2 additions & 0 deletions tests/async_patchers.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ async def shell_fail_server(self, cmd):

PATCH_ADB_SERVER_RUNTIME_ERROR = async_patch("{}.{}.device".format(__name__, CLIENT_ASYNC_FAKE_SUCCESS), side_effect=RuntimeError)

PATCH_ADB_SERVER_SCREENCAP_INDEX_ERROR = patch("{}.{}.screencap".format(__name__, DEVICE_ASYNC_FAKE), side_effect=IndexError)


class CustomException(Exception):
"""A custom exception type."""
Expand Down
2 changes: 2 additions & 0 deletions tests/patchers.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ def shell_fail_server(self, cmd):

PATCH_ADB_SERVER_RUNTIME_ERROR = patch("{}.{}.device".format(__name__, CLIENT_FAKE_SUCCESS), side_effect=RuntimeError)

PATCH_ADB_SERVER_SCREENCAP_INDEX_ERROR = patch("{}.{}.screencap".format(__name__, DEVICE_FAKE), side_effect=IndexError)


class CustomException(Exception):
"""A custom exception type."""
Expand Down
11 changes: 11 additions & 0 deletions tests/test_adb_manager_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,17 @@ async def test_connect_fail_server(self):
self.assertFalse(self.adb.available)
self.assertFalse(self.adb._available)

@awaiter
async def test_screencap_index_error(self):
"""Test when pure-python-adb gets an ``IndexError``.
"""
with async_patchers.patch_connect(True)[self.PATCH_KEY]:
self.assertTrue(await self.adb.connect())

with async_patchers.PATCH_ADB_SERVER_SCREENCAP_INDEX_ERROR:
self.assertIsNone(await self.adb.screencap())


class TestADBPythonAsyncWithAuthentication(unittest.TestCase):
"""Test the `ADBPythonAsync` class."""
Expand Down
46 changes: 46 additions & 0 deletions tests/test_adb_manager_async_temp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import sys
import unittest
from unittest.mock import patch

sys.path.insert(0, '..')

from androidtv.adb_manager.adb_manager_async import ClientAsync

from .async_wrapper import awaiter
from . import patchers


class TestAsyncClientDevice(unittest.TestCase):
"""Test the ``ClientAsync`` and ``DeviceAsync`` classes defined in ``adb_manager_async.py``.
This file can be removed once true async support for using an ADB server is available.
"""

@awaiter
async def test_async_client_device(self):
with patch("androidtv.adb_manager.adb_manager_async.Client", patchers.ClientFakeSuccess):
client = ClientAsync("host", "port")

device = await client.device("serial")

with patch("{}.DeviceFake.shell".format(patchers.__name__)):
await device.shell("test")

with patch("{}.DeviceFake.push".format(patchers.__name__)):
await device.push("local_path", "device_path")

with patch("{}.DeviceFake.pull".format(patchers.__name__)):
await device.pull("device_path", "local_path")

with patch("{}.DeviceFake.screencap".format(patchers.__name__)):
await device.screencap()

@awaiter
async def test_async_client_device_fail(self):
with patch("androidtv.adb_manager.adb_manager_async.Client", patchers.ClientFakeFail):
client = ClientAsync("host", "port")

device = await client.device("serial")

self.assertFalse(device)
10 changes: 10 additions & 0 deletions tests/test_adb_manager_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,16 @@ def test_connect_fail_server(self):
self.assertFalse(self.adb.available)
self.assertFalse(self.adb._available)

def test_screencap_index_error(self):
"""Test when pure-python-adb gets an ``IndexError``.
"""
with patchers.patch_connect(True)[self.PATCH_KEY]:
self.assertTrue(self.adb.connect())

with patchers.PATCH_ADB_SERVER_SCREENCAP_INDEX_ERROR:
self.assertIsNone(self.adb.screencap())


class TestADBPythonSyncWithAuthentication(unittest.TestCase):
"""Test the `ADBPythonSync` class."""
Expand Down

0 comments on commit d081fd5

Please sign in to comment.