diff --git a/bumble/avrcp.py b/bumble/avrcp.py index 5be5879..c7422bc 100644 --- a/bumble/avrcp.py +++ b/bumble/avrcp.py @@ -1698,6 +1698,14 @@ class Delegate: ) -> None: self.player_app_settings[attribute] = value + async def play_item(self, scope: Scope, uid: int, uid_counter: int) -> None: + logger.debug( + "@@@ play_item: scope=%s, uid=%s, uid_counter=%s", + scope, + uid, + uid_counter, + ) + # TODO add other delegate methods @@ -2385,6 +2393,8 @@ class Protocol(utils.EventEmitter): self._on_get_current_player_application_setting_value_command( transaction_label, command ) + case PlayItemCommand(): + self._on_play_item_command(transaction_label, command) case _: # Not supported. # TODO: check that this is the right way to respond in this case. @@ -2763,6 +2773,26 @@ class Protocol(utils.EventEmitter): self._delegate_command(transaction_label, command, set_player_app_settings()) + def _on_play_item_command( + self, + transaction_label: int, + command: PlayItemCommand, + ) -> None: + logger.debug("<<< AVRCP command PDU: %s", command) + + async def play_item() -> None: + await self.delegate.play_item( + scope=command.scope, uid=command.uid, uid_counter=command.uid_counter + ) + + self.send_avrcp_response( + transaction_label, + avc.ResponseFrame.ResponseCode.IMPLEMENTED_OR_STABLE, + PlayItemResponse(status=StatusCode.OPERATION_COMPLETED), + ) + + self._delegate_command(transaction_label, command, play_item()) + def _on_register_notification_command( self, transaction_label: int, command: RegisterNotificationCommand ) -> None: diff --git a/tests/avrcp_test.py b/tests/avrcp_test.py index ac164d4..a40674f 100644 --- a/tests/avrcp_test.py +++ b/tests/avrcp_test.py @@ -20,6 +20,7 @@ from __future__ import annotations import asyncio import struct from collections.abc import Sequence +from unittest import mock import pytest @@ -640,6 +641,26 @@ async def test_get_set_player_app_settings(): assert actual_settings == expected_settings +# ----------------------------------------------------------------------------- +@pytest.mark.asyncio +async def test_play_item(): + two_devices: TwoDevices = await TwoDevices.create_with_avdtp() + + delegate = two_devices.protocols[1].delegate + + with mock.patch.object(delegate, delegate.play_item.__name__) as play_item_mock: + await two_devices.protocols[0].send_avrcp_command( + avc.CommandFrame.CommandType.CONTROL, + avrcp.PlayItemCommand( + scope=avrcp.Scope.MEDIA_PLAYER_LIST, uid=0, uid_counter=1 + ), + ) + + play_item_mock.assert_called_once_with( + scope=avrcp.Scope.MEDIA_PLAYER_LIST, uid=0, uid_counter=1 + ) + + # ----------------------------------------------------------------------------- @pytest.mark.asyncio async def test_monitor_volume():