diff --git a/androidtv/androidtv.py b/androidtv/androidtv.py index e1ba4813..1cf71924 100644 --- a/androidtv/androidtv.py +++ b/androidtv/androidtv.py @@ -340,6 +340,25 @@ def get_properties_dict(self, get_running_apps=True, lazy=True): 'volume': volume, 'running_apps': running_apps} + # ======================================================================= # + # # + # Properties # + # # + # ======================================================================= # + @property + def running_apps(self): + """Return a list of running user applications. + + Returns + ------- + list + A list of the running apps + + """ + running_apps_response = self._adb.shell(constants.CMD_ANDROIDTV_RUNNING_APPS) + + return self._running_apps(running_apps_response) + # ======================================================================= # # # # turn on/off methods # diff --git a/androidtv/basetv.py b/androidtv/basetv.py index d4f48abe..f2e75a18 100644 --- a/androidtv/basetv.py +++ b/androidtv/basetv.py @@ -445,20 +445,6 @@ def media_session_state(self): return media_session_state - @property - def running_apps(self): - """Return a list of running user applications. - - Returns - ------- - list - A list of the running apps - - """ - running_apps_response = self._adb.shell(constants.CMD_RUNNING_APPS) - - return self._running_apps(running_apps_response) - @property def screen_on(self): """Check if the screen is on. diff --git a/androidtv/constants.py b/androidtv/constants.py index 432edafd..db79ca55 100644 --- a/androidtv/constants.py +++ b/androidtv/constants.py @@ -32,8 +32,11 @@ #: Determine the current app and get the state from ``dumpsys media_session`` CMD_MEDIA_SESSION_STATE_FULL = CMD_CURRENT_APP + " && " + CMD_MEDIA_SESSION_STATE -#: Get the running apps -CMD_RUNNING_APPS = "ps | grep u0_a" +#: Get the running apps for an Android TV device +CMD_ANDROIDTV_RUNNING_APPS = "ps -A | grep u0_a" + +#: Get the running apps for a Fire TV device +CMD_FIRETV_RUNNING_APPS = "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')" @@ -45,25 +48,25 @@ CMD_WAKE_LOCK_SIZE = "dumpsys power | grep Locks | grep 'size='" #: Get the properties for an :py:class:`~androidtv.androidtv.AndroidTV` device (``lazy=True, get_running_apps=True``); see :py:meth:`androidtv.androidtv.AndroidTV.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_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_ANDROIDTV_RUNNING_APPS #: Get the properties for an :py:class:`~androidtv.androidtv.AndroidTV` device (``lazy=True, get_running_apps=False``); see :py:meth:`androidtv.androidtv.AndroidTV.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 :py:class:`~androidtv.androidtv.AndroidTV` device (``lazy=False, get_running_apps=True``); see :py:meth:`androidtv.androidtv.AndroidTV.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_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_ANDROIDTV_RUNNING_APPS #: Get the properties for an :py:class:`~androidtv.androidtv.AndroidTV` device (``lazy=False, get_running_apps=False``); see :py:meth:`androidtv.androidtv.AndroidTV.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 :py:class:`~androidtv.firetv.FireTV` device (``lazy=True, get_running_apps=True``); see :py:meth:`androidtv.firetv.FireTV.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_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_FIRETV_RUNNING_APPS #: Get the properties for a :py:class:`~androidtv.firetv.FireTV` device (``lazy=True, get_running_apps=False``); see :py:meth:`androidtv.firetv.FireTV.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 :py:class:`~androidtv.firetv.FireTV` device (``lazy=False, get_running_apps=True``); see :py:meth:`androidtv.firetv.FireTV.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_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_FIRETV_RUNNING_APPS #: Get the properties for a :py:class:`~androidtv.firetv.FireTV` device (``lazy=False, get_running_apps=False``); see :py:meth:`androidtv.firetv.FireTV.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.py b/androidtv/firetv.py index ba90e331..d77727ff 100644 --- a/androidtv/firetv.py +++ b/androidtv/firetv.py @@ -398,6 +398,25 @@ def get_properties_dict(self, get_running_apps=True, lazy=True): 'media_session_state': media_session_state, 'running_apps': running_apps} + # ======================================================================= # + # # + # Properties # + # # + # ======================================================================= # + @property + def running_apps(self): + """Return a list of running user applications. + + Returns + ------- + list + A list of the running apps + + """ + running_apps_response = self._adb.shell(constants.CMD_FIRETV_RUNNING_APPS) + + return self._running_apps(running_apps_response) + # ======================================================================= # # # # turn on/off methods # diff --git a/tests/test_androidtv.py b/tests/test_androidtv.py index c70ddaf9..3f92662b 100644 --- a/tests/test_androidtv.py +++ b/tests/test_androidtv.py @@ -304,9 +304,11 @@ Devices: speaker""" -RUNNING_APPS = """ -u0_a2 17243 197 998628 24932 ffffffff 00000000 S com.amazon.device.controllermanager -u0_a2 17374 197 995368 20764 ffffffff 00000000 S com.amazon.device.controllermanager:BluetoothReceiver""" +RUNNING_APPS_OUTPUT = """ +u0_a18 316 197 1189204 115000 ffffffff 00000000 S com.netflix.ninja +u0_a2 15121 197 998628 24628 ffffffff 00000000 S com.amazon.device.controllermanager""" + +RUNNING_APPS_LIST = ['com.netflix.ninja', 'com.amazon.device.controllermanager'] GET_PROPERTIES_OUTPUT1 = "" @@ -555,6 +557,22 @@ def test_start_intent(self): self.atv.start_intent("TEST") self.assertEqual(getattr(self.atv._adb, self.ADB_ATTR).shell_cmd, "am start -a android.intent.action.VIEW -d TEST") + def test_running_apps(self): + """Check that the ``running_apps`` property works correctly. + + """ + with patchers.patch_shell(None)[self.PATCH_KEY]: + running_apps = self.atv.running_apps + self.assertIsNone(running_apps, None) + + with patchers.patch_shell('')[self.PATCH_KEY]: + running_apps = self.atv.running_apps + self.assertIsNone(running_apps, None) + + with patchers.patch_shell(RUNNING_APPS_OUTPUT)[self.PATCH_KEY]: + running_apps = self.atv.running_apps + self.assertListEqual(running_apps, RUNNING_APPS_LIST) + def test_device(self): """Check that the ``device`` property works correctly. @@ -844,15 +862,19 @@ def test_get_properties(self): properties = self.atv.get_properties_dict(get_running_apps=True, lazy=True) self.assertEqual(properties, GET_PROPERTIES_DICT_PLEX_PAUSED) - with patchers.patch_shell(GET_PROPERTIES_OUTPUT_PLEX_PAUSED + RUNNING_APPS)[self.PATCH_KEY]: + with patchers.patch_shell(GET_PROPERTIES_OUTPUT_PLEX_PAUSED)[self.PATCH_KEY]: + properties = self.atv.get_properties_dict(get_running_apps=False, lazy=True) + self.assertEqual(properties, GET_PROPERTIES_DICT_PLEX_PAUSED) + + with patchers.patch_shell(GET_PROPERTIES_OUTPUT_PLEX_PAUSED + RUNNING_APPS_OUTPUT)[self.PATCH_KEY]: true_properties = GET_PROPERTIES_DICT_PLEX_PAUSED.copy() - true_properties['running_apps'] = ['com.amazon.device.controllermanager', 'com.amazon.device.controllermanager:BluetoothReceiver'] + true_properties['running_apps'] = RUNNING_APPS_LIST properties = self.atv.get_properties_dict(get_running_apps=True, lazy=True) self.assertEqual(properties, true_properties) - with patchers.patch_shell(GET_PROPERTIES_OUTPUT_PLEX_PAUSED + RUNNING_APPS)[self.PATCH_KEY]: + with patchers.patch_shell(GET_PROPERTIES_OUTPUT_PLEX_PAUSED + RUNNING_APPS_OUTPUT)[self.PATCH_KEY]: true_properties = GET_PROPERTIES_DICT_PLEX_PAUSED.copy() - true_properties['running_apps'] = ['com.amazon.device.controllermanager', 'com.amazon.device.controllermanager:BluetoothReceiver'] + true_properties['running_apps'] = RUNNING_APPS_LIST properties = self.atv.get_properties_dict(get_running_apps=True, lazy=False) self.assertEqual(properties, true_properties) @@ -904,10 +926,10 @@ def test_update(self): state = self.atv.update() self.assertEqual(state[0], constants.STATE_IDLE) - with patchers.patch_shell(GET_PROPERTIES_OUTPUT3 + RUNNING_APPS)[self.PATCH_KEY]: + with patchers.patch_shell(GET_PROPERTIES_OUTPUT3 + RUNNING_APPS_OUTPUT)[self.PATCH_KEY]: self.atv._state_detection_rules = None state = self.atv.update(get_running_apps=True) - true_state = STATE3[:2] + (['com.amazon.device.controllermanager', 'com.amazon.device.controllermanager:BluetoothReceiver'],) + STATE3[3:] + true_state = STATE3[:2] + (RUNNING_APPS_LIST,) + STATE3[3:] self.assertTupleEqual(state, true_state) def assertUpdate(self, get_properties, update): diff --git a/tests/test_basetv.py b/tests/test_basetv.py index 2b7b372d..2850b863 100644 --- a/tests/test_basetv.py +++ b/tests/test_basetv.py @@ -58,11 +58,6 @@ MEDIA_SESSION_STATE_OUTPUT = "com.amazon.tv.launcher\nstate=PlaybackState {state=2, position=0, buffered position=0, speed=0.0, updated=65749, actions=240640, custom actions=[], active item id=-1, error=null}" -RUNNING_APPS_OUTPUT = """u0_a18 316 197 1189204 115000 ffffffff 00000000 S com.netflix.ninja -u0_a2 15121 197 998628 24628 ffffffff 00000000 S com.amazon.device.controllermanager""" - -RUNNING_APPS_LIST = ['com.netflix.ninja', 'com.amazon.device.controllermanager'] - STATE_DETECTION_RULES1 = {'com.amazon.tv.launcher': ['off']} STATE_DETECTION_RULES2 = {'com.amazon.tv.launcher': ['media_session_state', 'off']} STATE_DETECTION_RULES3 = {'com.amazon.tv.launcher': [{'standby': {'wake_lock_size': 2}}]} @@ -385,22 +380,6 @@ def test_media_session_state(self): media_session_state = self.btv.media_session_state self.assertEqual(media_session_state, 2) - def test_running_apps(self): - """Check that the ``running_apps`` property works correctly. - - """ - with patchers.patch_shell(None)[self.PATCH_KEY]: - running_apps = self.btv.running_apps - self.assertIsNone(running_apps, None) - - with patchers.patch_shell('')[self.PATCH_KEY]: - running_apps = self.btv.running_apps - self.assertIsNone(running_apps, None) - - with patchers.patch_shell(RUNNING_APPS_OUTPUT)[self.PATCH_KEY]: - running_apps = self.btv.running_apps - self.assertListEqual(running_apps, RUNNING_APPS_LIST) - def test_screen_on(self): """Check that the ``screen_on`` property works correctly. diff --git a/tests/test_firetv.py b/tests/test_firetv.py index 39d99188..a13f52cc 100644 --- a/tests/test_firetv.py +++ b/tests/test_firetv.py @@ -18,6 +18,11 @@ CURRENT_APP_OUTPUT = "com.amazon.tv.launcher" +RUNNING_APPS_OUTPUT = """u0_a18 316 197 1189204 115000 ffffffff 00000000 S com.netflix.ninja +u0_a2 15121 197 998628 24628 ffffffff 00000000 S com.amazon.device.controllermanager""" + +RUNNING_APPS_LIST = ['com.netflix.ninja', 'com.amazon.device.controllermanager'] + GET_PROPERTIES_OUTPUT1 = "" GET_PROPERTIES_DICT1 = {'screen_on': False, 'awake': False, @@ -159,6 +164,22 @@ def test_launch_app_stop_app(self): self.ftv.stop_app("TEST") self.assertEqual(getattr(self.ftv._adb, self.ADB_ATTR).shell_cmd, "am force-stop TEST") + def test_running_apps(self): + """Check that the ``running_apps`` property works correctly. + + """ + with patchers.patch_shell(None)[self.PATCH_KEY]: + running_apps = self.ftv.running_apps + self.assertIsNone(running_apps, None) + + with patchers.patch_shell('')[self.PATCH_KEY]: + running_apps = self.ftv.running_apps + self.assertIsNone(running_apps, None) + + with patchers.patch_shell(RUNNING_APPS_OUTPUT)[self.PATCH_KEY]: + running_apps = self.ftv.running_apps + self.assertListEqual(running_apps, RUNNING_APPS_LIST) + def test_get_properties(self): """Check that ``get_properties()`` works correctly.