Skip to content

Commit

Permalink
Enable customizing commands
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffLIrion committed Jan 31, 2022
1 parent e6b3649 commit 5180fc3
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 0 deletions.
38 changes: 38 additions & 0 deletions androidtv/basetv/basetv.py
Expand Up @@ -91,11 +91,31 @@ def __init__(
# the max volume level (determined when first getting the volume level)
self.max_volume = None

# Customizable commands
self._custom_commands = {}

# ======================================================================= #
# #
# Device-specific ADB commands #
# #
# ======================================================================= #
def customize_command(self, custom_command, value):
"""Customize a command used to retrieve properties.
Parameters
----------
custom_command : str
The name of the command that will be customized; it must be in `constants.CUSTOMIZABLE_COMMANDS`
value : str, None
The custom ADB command that will be used, or ``None`` if the custom command should be deleted
"""
if custom_command in constants.CUSTOMIZABLE_COMMANDS:
if value is not None:
self._custom_commands[custom_command] = value
elif custom_command in self._custom_commands:
del self._custom_commands[custom_command]

def _cmd_current_app(self):
"""Get the command used to retrieve the current app for this device.
Expand All @@ -105,6 +125,9 @@ def _cmd_current_app(self):
The device-specific ADB shell command used to determine the current app
"""
if constants.CUSTOM_CURRENT_APP in self._custom_commands:
return self._custom_commands[constants.CUSTOM_CURRENT_APP]

# Is this a Google Chromecast Android TV?
if (
self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV
Expand All @@ -124,6 +147,9 @@ def _cmd_current_app_media_session_state(self):
The device-specific ADB shell command used to determine the current app and media session state
"""
if constants.CUSTOM_CURRENT_APP_MEDIA_SESSION_STATE in self._custom_commands:
return self._custom_commands[constants.CUSTOM_CURRENT_APP_MEDIA_SESSION_STATE]

# Is this a Google Chromecast Android TV?
if (
self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV
Expand All @@ -148,6 +174,9 @@ def _cmd_launch_app(self, app):
The device-specific command to launch the app
"""
if constants.CUSTOM_LAUNCH_APP in self._custom_commands:
return self._custom_commands[constants.CUSTOM_LAUNCH_APP].format(app)

# Is this a Google Chromecast Android TV?
if (
self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV
Expand All @@ -167,6 +196,9 @@ def _cmd_running_apps(self):
The device-specific ADB shell command used to determine the running apps
"""
if constants.CUSTOM_RUNNING_APPS in self._custom_commands:
return self._custom_commands[constants.CUSTOM_RUNNING_APPS]

if self.DEVICE_ENUM == constants.DeviceEnum.FIRETV:
return constants.CMD_RUNNING_APPS_FIRETV

Expand All @@ -181,6 +213,9 @@ def _cmd_turn_off(self):
The device-specific ADB shell command used to turn off the device
"""
if constants.CUSTOM_TURN_OFF in self._custom_commands:
return self._custom_commands[constants.CUSTOM_TURN_OFF]

if self.DEVICE_ENUM == constants.DeviceEnum.FIRETV:
return constants.CMD_TURN_OFF_FIRETV

Expand All @@ -195,6 +230,9 @@ def _cmd_turn_on(self):
The device-specific ADB shell command used to turn on the device
"""
if constants.CUSTOM_TURN_ON in self._custom_commands:
return self._custom_commands[constants.CUSTOM_TURN_ON]

if self.DEVICE_ENUM == constants.DeviceEnum.FIRETV:
return constants.CMD_TURN_ON_FIRETV

Expand Down
16 changes: 16 additions & 0 deletions androidtv/constants.py
Expand Up @@ -34,6 +34,22 @@ class DeviceEnum(IntEnum):
INTENT_LAUNCH = "android.intent.category.LAUNCHER"
INTENT_HOME = "android.intent.category.HOME"

# Customizable commands
CUSTOM_CURRENT_APP = "current_app"
CUSTOM_CURRENT_APP_MEDIA_SESSION_STATE = "current_app_media_session_state"
CUSTOM_LAUNCH_APP = "launch_app"
CUSTOM_RUNNING_APPS = "running_apps"
CUSTOM_TURN_OFF = "turn_off"
CUSTOM_TURN_ON = "turn_on"
CUSTOMIZABLE_COMMANDS = {
CUSTOM_CURRENT_APP,
CUSTOM_CURRENT_APP_MEDIA_SESSION_STATE,
CUSTOM_LAUNCH_APP,
CUSTOM_RUNNING_APPS,
CUSTOM_TURN_OFF,
CUSTOM_TURN_ON,
}


# echo '1' if the previous shell command was successful
CMD_SUCCESS1 = r" && echo -e '1\c'"
Expand Down
37 changes: 37 additions & 0 deletions tests/test_androidtv_sync.py
Expand Up @@ -591,6 +591,43 @@ def test_state_detection(self):
(constants.STATE_IDLE, "unknown", ["unknown"], "hmdi_arc", False, 0.5, None),
)

def test_customize_command(self):
self.atv.customize_command(constants.CUSTOM_CURRENT_APP, "1")
with patch.object(self.atv._adb, "shell") as patched:
self.atv.current_app()
patched.assert_called_with("1")

self.atv.customize_command(constants.CUSTOM_CURRENT_APP_MEDIA_SESSION_STATE, "2")
with patch.object(self.atv._adb, "shell") as patched:
self.atv.current_app_media_session_state()
patched.assert_called_with("2")

self.atv.customize_command(constants.CUSTOM_LAUNCH_APP, "this is a {}")
with patch.object(self.atv._adb, "shell") as patched:
self.atv.launch_app("test")
patched.assert_called_with("this is a test")

self.atv.customize_command(constants.CUSTOM_RUNNING_APPS, "3")
with patch.object(self.atv._adb, "shell") as patched:
self.atv.running_apps()
patched.assert_called_with("3")

self.atv.customize_command(constants.CUSTOM_TURN_OFF, "4")
with patch.object(self.atv._adb, "shell") as patched:
self.atv.turn_off()
patched.assert_called_with("4")

self.atv.customize_command(constants.CUSTOM_TURN_ON, "5")
with patch.object(self.atv._adb, "shell") as patched:
self.atv.turn_on()
patched.assert_called_with("5")

# Delete a custom command
self.atv.customize_command(constants.CUSTOM_TURN_ON, None)
with patch.object(self.atv._adb, "shell") as patched:
self.atv.turn_on()
patched.assert_called_with(constants.CMD_TURN_ON_ANDROIDTV)


class TestAndroidTVSyncServer(TestAndroidTVSyncPython):
PATCH_KEY = "server"
Expand Down

0 comments on commit 5180fc3

Please sign in to comment.