From 73c3fd50856f98d877001a4a2ba63cb00531ced5 Mon Sep 17 00:00:00 2001 From: Jeff Irion Date: Tue, 20 Oct 2020 17:18:51 -0700 Subject: [PATCH] Add get_hdmi_input() function --- androidtv/androidtv/androidtv_async.py | 2 +- androidtv/androidtv/androidtv_sync.py | 2 +- androidtv/basetv/basetv.py | 17 +++++++++++++++++ androidtv/basetv/basetv_async.py | 11 +++++++++++ androidtv/basetv/basetv_sync.py | 11 +++++++++++ androidtv/constants.py | 19 +++++++++++-------- androidtv/firetv/firetv_async.py | 2 +- androidtv/firetv/firetv_sync.py | 2 +- tests/test_basetv_async.py | 11 +++++++++++ tests/test_basetv_sync.py | 10 ++++++++++ 10 files changed, 75 insertions(+), 12 deletions(-) diff --git a/androidtv/androidtv/androidtv_async.py b/androidtv/androidtv/androidtv_async.py index ba48a294..877c5512 100644 --- a/androidtv/androidtv/androidtv_async.py +++ b/androidtv/androidtv/androidtv_async.py @@ -173,7 +173,7 @@ async def running_apps(self): A list of the running apps """ - running_apps_response = await self._adb.shell(constants.CMD_ANDROIDTV_RUNNING_APPS) + running_apps_response = await self._adb.shell(constants.CMD_RUNNING_APPS_ANDROIDTV) return self._running_apps(running_apps_response) diff --git a/androidtv/androidtv/androidtv_sync.py b/androidtv/androidtv/androidtv_sync.py index d927d007..935947c1 100644 --- a/androidtv/androidtv/androidtv_sync.py +++ b/androidtv/androidtv/androidtv_sync.py @@ -173,7 +173,7 @@ def running_apps(self): A list of the running apps """ - running_apps_response = self._adb.shell(constants.CMD_ANDROIDTV_RUNNING_APPS) + running_apps_response = self._adb.shell(constants.CMD_RUNNING_APPS_ANDROIDTV) return self._running_apps(running_apps_response) diff --git a/androidtv/basetv/basetv.py b/androidtv/basetv/basetv.py index bab9f568..7ee333a0 100644 --- a/androidtv/basetv/basetv.py +++ b/androidtv/basetv/basetv.py @@ -359,6 +359,23 @@ def _current_app_media_session_state(self, media_session_state_response): return current_app, media_session_state + @staticmethod + def _get_hdmi_input(hdmi_response): + """Get the HDMI input from the output of :py:const:`androidtv.constants.CMD_HDMI_INPUT`. + + Parameters + ---------- + hdmi_response : str, None + The output of :py:const:`androidtv.constants.CMD_HDMI_INPUT` + + Returns + ------- + str, None + The HDMI input, or ``None`` if it could not be determined + + """ + return hdmi_response if hdmi_response else None + @staticmethod def _is_volume_muted(stream_music): """Determine whether or not the volume is muted from the ``STREAM_MUSIC`` block from ``adb shell dumpsys audio``. diff --git a/androidtv/basetv/basetv_async.py b/androidtv/basetv/basetv_async.py index 9e9a8693..5465952c 100644 --- a/androidtv/basetv/basetv_async.py +++ b/androidtv/basetv/basetv_async.py @@ -254,6 +254,17 @@ async def current_app(self): return self._current_app(current_app_response) + async def get_hdmi_input(self): + """Get the HDMI input from the output of :py:const:`androidtv.constants.CMD_HDMI_INPUT`. + + Returns + ------- + str, None + The HDMI input, or ``None`` if it could not be determined + + """ + return self._get_hdmi_input(await self._adb.shell(constants.CMD_HDMI_INPUT)) + async def is_volume_muted(self): """Whether or not the volume is muted. diff --git a/androidtv/basetv/basetv_sync.py b/androidtv/basetv/basetv_sync.py index 28e9d422..2ba2d161 100644 --- a/androidtv/basetv/basetv_sync.py +++ b/androidtv/basetv/basetv_sync.py @@ -254,6 +254,17 @@ def current_app(self): return self._current_app(current_app_response) + def get_hdmi_input(self): + """Get the HDMI input from the output of :py:const:`androidtv.constants.CMD_HDMI_INPUT`. + + Returns + ------- + str, None + The HDMI input, or ``None`` if it could not be determined + + """ + return self._get_hdmi_input(self._adb.shell(constants.CMD_HDMI_INPUT)) + def is_volume_muted(self): """Whether or not the volume is muted. diff --git a/androidtv/constants.py b/androidtv/constants.py index 759267ab..b8d259be 100644 --- a/androidtv/constants.py +++ b/androidtv/constants.py @@ -34,6 +34,9 @@ #: Get the current app for a Google TV device CMD_CURRENT_APP_GOOGLE_TV = "CURRENT_APP=$(dumpsys window windows | grep 'Window #1') && CURRENT_APP=${CURRENT_APP#*{* * } && CURRENT_APP=${CURRENT_APP%%/*} && echo $CURRENT_APP" +#: Get the HDMI input +CMD_HDMI_INPUT = "dumpsys activity starter | grep -o 'HDMIInputService\\/HW[0-9]' -m 1 | grep -o 'HW[0-9]'" + #: Launch an app if it is not already the current app CMD_LAUNCH_APP = "CURRENT_APP=$(dumpsys window windows | grep mCurrentFocus) && CURRENT_APP=${{CURRENT_APP#*{{* * }} && CURRENT_APP=${{CURRENT_APP%%/*}} && if [ $CURRENT_APP != '{0}' ]; then monkey -p {0} -c " + INTENT_LAUNCH + " --pct-syskeys 0 1; fi" @@ -44,10 +47,10 @@ CMD_MEDIA_SESSION_STATE_FULL = CMD_CURRENT_APP + " && " + CMD_MEDIA_SESSION_STATE #: Get the running apps for an Android TV device -CMD_ANDROIDTV_RUNNING_APPS = "ps -A | grep u0_a" +CMD_RUNNING_APPS_ANDROIDTV = "ps -A | grep u0_a" #: Get the running apps for a Fire TV device -CMD_FIRETV_RUNNING_APPS = "ps | grep u0_a" +CMD_RUNNING_APPS_FIRETV = "ps | grep u0_a" #: Determine if the device is on CMD_SCREEN_ON = "(dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true')" @@ -59,37 +62,37 @@ CMD_WAKE_LOCK_SIZE = "dumpsys power | grep Locks | grep 'size='" #: Get the properties for an Android TV device (``lazy=True, get_running_apps=True``); see :py:meth:`androidtv.androidtv.androidtv_sync.AndroidTVSync.get_properties` and :py:meth:`androidtv.androidtv.androidtv_async.AndroidTVAsync.get_properties` -CMD_ANDROIDTV_PROPERTIES_LAZY_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1 + " && " + CMD_AWAKE + CMD_SUCCESS1 + " && (" + CMD_AUDIO_STATE + ") && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP + " && (" + CMD_MEDIA_SESSION_STATE + " || echo) && " + CMD_STREAM_MUSIC + " && " + CMD_ANDROIDTV_RUNNING_APPS +CMD_ANDROIDTV_PROPERTIES_LAZY_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1 + " && " + CMD_AWAKE + CMD_SUCCESS1 + " && (" + CMD_AUDIO_STATE + ") && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP + " && (" + CMD_MEDIA_SESSION_STATE + " || echo) && " + CMD_STREAM_MUSIC + " && " + CMD_RUNNING_APPS_ANDROIDTV #: Get the properties for an Android TV device (``lazy=True, get_running_apps=False``); see :py:meth:`androidtv.androidtv.androidtv_sync.AndroidTVSync.get_properties` and :py:meth:`androidtv.androidtv.androidtv_async.AndroidTVAsync.get_properties` CMD_ANDROIDTV_PROPERTIES_LAZY_NO_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1 + " && " + CMD_AWAKE + CMD_SUCCESS1 + " && (" + CMD_AUDIO_STATE + ") && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP + " && (" + CMD_MEDIA_SESSION_STATE + " || echo) && " + CMD_STREAM_MUSIC #: Get the properties for an Android TV device (``lazy=False, get_running_apps=True``); see :py:meth:`androidtv.androidtv.androidtv_sync.AndroidTVSync.get_properties` and :py:meth:`androidtv.androidtv.androidtv_async.AndroidTVAsync.get_properties` -CMD_ANDROIDTV_PROPERTIES_NOT_LAZY_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1_FAILURE0 + " && " + CMD_AWAKE + CMD_SUCCESS1_FAILURE0 + " && (" + CMD_AUDIO_STATE + ") && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP + " && (" + CMD_MEDIA_SESSION_STATE + " || echo) && " + CMD_STREAM_MUSIC + " && " + CMD_ANDROIDTV_RUNNING_APPS +CMD_ANDROIDTV_PROPERTIES_NOT_LAZY_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1_FAILURE0 + " && " + CMD_AWAKE + CMD_SUCCESS1_FAILURE0 + " && (" + CMD_AUDIO_STATE + ") && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP + " && (" + CMD_MEDIA_SESSION_STATE + " || echo) && " + CMD_STREAM_MUSIC + " && " + CMD_RUNNING_APPS_ANDROIDTV #: Get the properties for an Android TV device (``lazy=False, get_running_apps=False``); see :py:meth:`androidtv.androidtv.androidtv_sync.AndroidTVSync.get_properties` and :py:meth:`androidtv.androidtv.androidtv_async.AndroidTVAsync.get_properties` CMD_ANDROIDTV_PROPERTIES_NOT_LAZY_NO_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1_FAILURE0 + " && " + CMD_AWAKE + CMD_SUCCESS1_FAILURE0 + " && (" + CMD_AUDIO_STATE + ") && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP + " && (" + CMD_MEDIA_SESSION_STATE + " || echo) && " + CMD_STREAM_MUSIC #: Get the properties for a Google TV device (``lazy=True, get_running_apps=True``); see :py:meth:`androidtv.androidtv.androidtv_sync.AndroidTVSync.get_properties` and :py:meth:`androidtv.androidtv.androidtv_async.AndroidTVAsync.get_properties` -CMD_GOOGLE_TV_PROPERTIES_LAZY_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1 + " && " + CMD_AWAKE + CMD_SUCCESS1 + " && (" + CMD_AUDIO_STATE + ") && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP_GOOGLE_TV + " && (" + CMD_MEDIA_SESSION_STATE + " || echo) && " + CMD_STREAM_MUSIC + " && " + CMD_ANDROIDTV_RUNNING_APPS +CMD_GOOGLE_TV_PROPERTIES_LAZY_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1 + " && " + CMD_AWAKE + CMD_SUCCESS1 + " && (" + CMD_AUDIO_STATE + ") && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP_GOOGLE_TV + " && (" + CMD_MEDIA_SESSION_STATE + " || echo) && " + CMD_STREAM_MUSIC + " && " + CMD_RUNNING_APPS_ANDROIDTV #: Get the properties for a Google TV device (``lazy=True, get_running_apps=False``); see :py:meth:`androidtv.androidtv.androidtv_sync.AndroidTVSync.get_properties` and :py:meth:`androidtv.androidtv.androidtv_async.AndroidTVAsync.get_properties` CMD_GOOGLE_TV_PROPERTIES_LAZY_NO_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1 + " && " + CMD_AWAKE + CMD_SUCCESS1 + " && (" + CMD_AUDIO_STATE + ") && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP_GOOGLE_TV + " && (" + CMD_MEDIA_SESSION_STATE + " || echo) && " + CMD_STREAM_MUSIC #: Get the properties for a Google TV device (``lazy=False, get_running_apps=True``); see :py:meth:`androidtv.androidtv.androidtv_sync.AndroidTVSync.get_properties` and :py:meth:`androidtv.androidtv.androidtv_async.AndroidTVAsync.get_properties` -CMD_GOOGLE_TV_PROPERTIES_NOT_LAZY_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1_FAILURE0 + " && " + CMD_AWAKE + CMD_SUCCESS1_FAILURE0 + " && (" + CMD_AUDIO_STATE + ") && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP_GOOGLE_TV + " && (" + CMD_MEDIA_SESSION_STATE + " || echo) && " + CMD_STREAM_MUSIC + " && " + CMD_ANDROIDTV_RUNNING_APPS +CMD_GOOGLE_TV_PROPERTIES_NOT_LAZY_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1_FAILURE0 + " && " + CMD_AWAKE + CMD_SUCCESS1_FAILURE0 + " && (" + CMD_AUDIO_STATE + ") && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP_GOOGLE_TV + " && (" + CMD_MEDIA_SESSION_STATE + " || echo) && " + CMD_STREAM_MUSIC + " && " + CMD_RUNNING_APPS_ANDROIDTV #: Get the properties for a Google TV device (``lazy=False, get_running_apps=False``); see :py:meth:`androidtv.androidtv.androidtv_sync.AndroidTVSync.get_properties` and :py:meth:`androidtv.androidtv.androidtv_async.AndroidTVAsync.get_properties` CMD_GOOGLE_TV_PROPERTIES_NOT_LAZY_NO_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1_FAILURE0 + " && " + CMD_AWAKE + CMD_SUCCESS1_FAILURE0 + " && (" + CMD_AUDIO_STATE + ") && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP_GOOGLE_TV + " && (" + CMD_MEDIA_SESSION_STATE + " || echo) && " + CMD_STREAM_MUSIC #: Get the properties for a Fire TV device (``lazy=True, get_running_apps=True``); see :py:meth:`androidtv.firetv.firetv_sync.FireTVSync.get_properties` and :py:meth:`androidtv.firetv.firetv_async.FireTVAsync.get_properties` -CMD_FIRETV_PROPERTIES_LAZY_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1 + " && " + CMD_AWAKE + CMD_SUCCESS1 + " && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP + " && (" + CMD_MEDIA_SESSION_STATE + " || echo) && " + CMD_FIRETV_RUNNING_APPS +CMD_FIRETV_PROPERTIES_LAZY_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1 + " && " + CMD_AWAKE + CMD_SUCCESS1 + " && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP + " && (" + CMD_MEDIA_SESSION_STATE + " || echo) && " + CMD_RUNNING_APPS_FIRETV #: Get the properties for a Fire TV device (``lazy=True, get_running_apps=False``); see :py:meth:`androidtv.firetv.firetv_sync.FireTVSync.get_properties` and :py:meth:`androidtv.firetv.firetv_async.FireTVAsync.get_properties` CMD_FIRETV_PROPERTIES_LAZY_NO_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1 + " && " + CMD_AWAKE + CMD_SUCCESS1 + " && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP + " && (" + CMD_MEDIA_SESSION_STATE + " || echo)" #: Get the properties for a Fire TV device (``lazy=False, get_running_apps=True``); see :py:meth:`androidtv.firetv.firetv_sync.FireTVSync.get_properties` and :py:meth:`androidtv.firetv.firetv_async.FireTVAsync.get_properties` -CMD_FIRETV_PROPERTIES_NOT_LAZY_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1_FAILURE0 + " && " + CMD_AWAKE + CMD_SUCCESS1_FAILURE0 + " && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP + " && (" + CMD_MEDIA_SESSION_STATE + " || echo) && " + CMD_FIRETV_RUNNING_APPS +CMD_FIRETV_PROPERTIES_NOT_LAZY_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1_FAILURE0 + " && " + CMD_AWAKE + CMD_SUCCESS1_FAILURE0 + " && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP + " && (" + CMD_MEDIA_SESSION_STATE + " || echo) && " + CMD_RUNNING_APPS_FIRETV #: Get the properties for a Fire TV device (``lazy=False, get_running_apps=False``); see :py:meth:`androidtv.firetv.firetv_sync.FireTVSync.get_properties` and :py:meth:`androidtv.firetv.firetv_async.FireTVAsync.get_properties` CMD_FIRETV_PROPERTIES_NOT_LAZY_NO_RUNNING_APPS = CMD_SCREEN_ON + CMD_SUCCESS1_FAILURE0 + " && " + CMD_AWAKE + CMD_SUCCESS1_FAILURE0 + " && " + CMD_WAKE_LOCK_SIZE + " && " + CMD_CURRENT_APP + " && (" + CMD_MEDIA_SESSION_STATE + " || echo)" diff --git a/androidtv/firetv/firetv_async.py b/androidtv/firetv/firetv_async.py index f8df3655..3f3077d0 100644 --- a/androidtv/firetv/firetv_async.py +++ b/androidtv/firetv/firetv_async.py @@ -155,7 +155,7 @@ async def running_apps(self): A list of the running apps """ - running_apps_response = await self._adb.shell(constants.CMD_FIRETV_RUNNING_APPS) + running_apps_response = await self._adb.shell(constants.CMD_RUNNING_APPS_FIRETV) return self._running_apps(running_apps_response) diff --git a/androidtv/firetv/firetv_sync.py b/androidtv/firetv/firetv_sync.py index d125f8cb..c7fb9df9 100644 --- a/androidtv/firetv/firetv_sync.py +++ b/androidtv/firetv/firetv_sync.py @@ -155,7 +155,7 @@ def running_apps(self): A list of the running apps """ - running_apps_response = self._adb.shell(constants.CMD_FIRETV_RUNNING_APPS) + running_apps_response = self._adb.shell(constants.CMD_RUNNING_APPS_FIRETV) return self._running_apps(running_apps_response) diff --git a/tests/test_basetv_async.py b/tests/test_basetv_async.py index daaec960..d248e677 100644 --- a/tests/test_basetv_async.py +++ b/tests/test_basetv_async.py @@ -477,6 +477,17 @@ async def test_wake_lock_size(self): with async_patchers.patch_shell('INVALID')[self.PATCH_KEY]: self.assertIsNone(await self.btv.wake_lock_size()) + @awaiter + async def test_get_hdmi_input(self): + """Check that the ``get_hdmi_input`` function works correctly. + + """ + with async_patchers.patch_shell("HDMI2")[self.PATCH_KEY]: + self.assertEqual(await self.btv.get_hdmi_input(), "HDMI2") + + with async_patchers.patch_shell("")[self.PATCH_KEY]: + self.assertIsNone(await self.btv.get_hdmi_input(), None) + @awaiter async def test_learn_sendevent(self): """Check that the ``learn_sendevent`` method works correctly. diff --git a/tests/test_basetv_sync.py b/tests/test_basetv_sync.py index 3032e8d9..3adcb81a 100644 --- a/tests/test_basetv_sync.py +++ b/tests/test_basetv_sync.py @@ -464,6 +464,16 @@ def test_wake_lock_size(self): with patchers.patch_shell('INVALID')[self.PATCH_KEY]: self.assertIsNone(self.btv.wake_lock_size()) + def test_get_hdmi_input(self): + """Check that the ``get_hdmi_input`` function works correctly. + + """ + with patchers.patch_shell("HDMI2")[self.PATCH_KEY]: + self.assertEqual(self.btv.get_hdmi_input(), "HDMI2") + + with patchers.patch_shell("")[self.PATCH_KEY]: + self.assertIsNone(self.btv.get_hdmi_input(), None) + def test_learn_sendevent(self): """Check that the ``learn_sendevent`` method works correctly.