Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions pyatv/protocols/companion/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ async def swipe(
y: float = float(start_y)
await self.hid_event(int(x), int(y), TouchAction.Press)
sleep_time = float(TOUCHPAD_DELAY_MS / 1000)
await asyncio.sleep(sleep_time)
current_time = time.time_ns()
while current_time < end_time:
x = x + float(end_x - x) * TOUCHPAD_DELAY_MS * 1000000 / (
Expand All @@ -352,10 +353,8 @@ async def swipe(
y = y + float(end_y - y) * TOUCHPAD_DELAY_MS * 1000000 / (
end_time - current_time
)
x = max(x, 0)
y = max(y, 0)
x = min(x, TOUCHPAD_WIDTH)
y = min(y, TOUCHPAD_HEIGHT)
x = max(min(start_x, end_x), min(x, max(start_x, end_x)))
y = max(min(start_y, end_y), min(y, max(start_y, end_y)))
await self.hid_event(int(x), int(y), TouchAction.Hold)
await asyncio.sleep(sleep_time)
current_time = time.time_ns()
Expand Down
51 changes: 51 additions & 0 deletions tests/protocols/companion/test_companion_swipe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""Tests for Companion touch gesture timing."""

from unittest.mock import patch

import pytest

from pyatv.const import TouchAction
from pyatv.protocols.companion.api import TOUCHPAD_DELAY_MS, CompanionAPI


@pytest.mark.asyncio
@pytest.mark.parametrize(
"coords",
[
(100, 500, 900, 500),
(900, 500, 100, 500),
(500, 100, 500, 900),
(500, 900, 500, 100),
],
)
@pytest.mark.parametrize("duration", [1, 16, 100])
async def test_swipe_event_timing_and_bounds(coords, duration):
now = 0
events = []

async def sleep(delay):
nonlocal now
now += int(delay * 1_000_000_000)

async def event(x, y, action):
events.append((now, x, y, action))

with (
patch("pyatv.protocols.companion.api.time.time_ns", side_effect=lambda: now),
patch("pyatv.protocols.companion.api.asyncio.sleep", side_effect=sleep),
):
api = CompanionAPI(None)
with patch.object(api, "hid_event", side_effect=event):
await api.swipe(*coords, duration)

assert events[0] == (0, *coords[:2], TouchAction.Press)
assert events[-1][1:] == (*coords[2:], TouchAction.Release)
assert events[-1][0] >= duration * 1_000_000
if duration > TOUCHPAD_DELAY_MS:
assert any(action is TouchAction.Hold for _, _, _, action in events)
for index, (timestamp, x, y, action) in enumerate(events[1:], 1):
assert timestamp > events[index - 1][0]
assert min(coords[0], coords[2]) <= x <= max(coords[0], coords[2])
assert min(coords[1], coords[3]) <= y <= max(coords[1], coords[3])
if action is TouchAction.Hold:
assert timestamp - events[index - 1][0] >= TOUCHPAD_DELAY_MS * 1_000_000