Skip to content

Commit

Permalink
Merge be59657 into 6e446d0
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffLIrion committed Oct 17, 2020
2 parents 6e446d0 + be59657 commit 2298502
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 9 deletions.
8 changes: 4 additions & 4 deletions androidtv/androidtv/androidtv_async.py
Expand Up @@ -122,14 +122,14 @@ async def get_properties(self, get_running_apps=True, lazy=False):
"""
if lazy:
if get_running_apps:
output = await self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_LAZY_RUNNING_APPS)
output = await self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_LAZY_RUNNING_APPS if not self._is_google_tv else constants.CMD_GOOGLE_TV_PROPERTIES_LAZY_RUNNING_APPS)
else:
output = await self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_LAZY_NO_RUNNING_APPS)
output = await self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_LAZY_NO_RUNNING_APPS if not self._is_google_tv else constants.CMD_GOOGLE_TV_PROPERTIES_LAZY_NO_RUNNING_APPS)
else:
if get_running_apps:
output = await self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_NOT_LAZY_RUNNING_APPS)
output = await self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_NOT_LAZY_RUNNING_APPS if not self._is_google_tv else constants.CMD_GOOGLE_TV_PROPERTIES_NOT_LAZY_RUNNING_APPS)
else:
output = await self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_NOT_LAZY_NO_RUNNING_APPS)
output = await self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_NOT_LAZY_NO_RUNNING_APPS if not self._is_google_tv else constants.CMD_GOOGLE_TV_PROPERTIES_NOT_LAZY_NO_RUNNING_APPS)
_LOGGER.debug("Android TV %s:%d `get_properties` response: %s", self.host, self.port, output)

return self._get_properties(output, get_running_apps)
Expand Down
8 changes: 4 additions & 4 deletions androidtv/androidtv/androidtv_sync.py
Expand Up @@ -122,14 +122,14 @@ def get_properties(self, get_running_apps=True, lazy=False):
"""
if lazy:
if get_running_apps:
output = self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_LAZY_RUNNING_APPS)
output = self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_LAZY_RUNNING_APPS if not self._is_google_tv else constants.CMD_GOOGLE_TV_PROPERTIES_LAZY_RUNNING_APPS)
else:
output = self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_LAZY_NO_RUNNING_APPS)
output = self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_LAZY_NO_RUNNING_APPS if not self._is_google_tv else constants.CMD_GOOGLE_TV_PROPERTIES_LAZY_NO_RUNNING_APPS)
else:
if get_running_apps:
output = self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_NOT_LAZY_RUNNING_APPS)
output = self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_NOT_LAZY_RUNNING_APPS if not self._is_google_tv else constants.CMD_GOOGLE_TV_PROPERTIES_NOT_LAZY_RUNNING_APPS)
else:
output = self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_NOT_LAZY_NO_RUNNING_APPS)
output = self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_NOT_LAZY_NO_RUNNING_APPS if not self._is_google_tv else constants.CMD_GOOGLE_TV_PROPERTIES_NOT_LAZY_NO_RUNNING_APPS)
_LOGGER.debug("Android TV %s:%d `get_properties` response: %s", self.host, self.port, output)

return self._get_properties(output, get_running_apps)
Expand Down
5 changes: 5 additions & 0 deletions androidtv/basetv/basetv.py
Expand Up @@ -75,6 +75,7 @@ def __init__(self, adb, host, port=5555, adbkey='', adb_server_ip='', adb_server
self.adb_server_port = adb_server_port
self._state_detection_rules = state_detection_rules
self.device_properties = {}
self._is_google_tv = False

# make sure the rules are valid
if self._state_detection_rules:
Expand Down Expand Up @@ -133,6 +134,10 @@ def _parse_device_properties(self, properties):

manufacturer, model, serialno, version, mac_wlan0_output, mac_eth0_output = lines

# Is this a Google Chromecast Android TV?
if "Google" in manufacturer and "Chromecast" in model:
self._is_google_tv = True

if not serialno.strip():
_LOGGER.warning("Could not obtain serialno for %s:%d, got: '%s'", self.host, self.port, serialno)
serialno = None
Expand Down
17 changes: 16 additions & 1 deletion androidtv/constants.py
Expand Up @@ -31,6 +31,9 @@
#: Get the current app
CMD_CURRENT_APP = "CURRENT_APP=$(dumpsys window windows | grep mCurrentFocus) && CURRENT_APP=${CURRENT_APP#*{* * } && CURRENT_APP=${CURRENT_APP%%/*} && echo $CURRENT_APP"

#: 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"

#: 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"

Expand All @@ -50,7 +53,7 @@
CMD_SCREEN_ON = "(dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true')"

#: Get the "STREAM_MUSIC" block from ``dumpsys audio``
CMD_STREAM_MUSIC = r"dumpsys audio | grep '\- STREAM_MUSIC:' -A 12"
CMD_STREAM_MUSIC = r"dumpsys audio | grep '\- STREAM_MUSIC:' -A 11"

#: Get the wake lock size
CMD_WAKE_LOCK_SIZE = "dumpsys power | grep Locks | grep 'size='"
Expand All @@ -67,6 +70,18 @@
#: 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

#: 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

#: 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

Expand Down
36 changes: 36 additions & 0 deletions tests/test_androidtv_sync.py
Expand Up @@ -213,6 +213,38 @@
'running_apps': None}
STATE_NONE = (None, None, None, None, None, None)

# Source: https://community.home-assistant.io/t/new-chromecast-w-android-tv-integration-only-showing-as-off-or-idle/234424/17
GET_PROPERTIES_OUTPUT_GOOGLE_TV = """111Wake Locks: size=4
com.google.android.youtube.tv
state=PlaybackState {state=3, position=610102, buffered position=0, speed=1.0, updated=234649304, actions=379, custom actions=[], active item id=-1, error=null}
- STREAM_MUSIC:
Muted: false
Min: 0
Max: 25
streamVolume:25
Current: 4 (headset): 10, 8 (headphone): 10, 400 (hdmi): 25, 4000000 (usb_headset): 6, 40000000 (default): 20
Devices: hdmi
- STREAM_ALARM:
Muted: false
Min: 1
Max: 7
streamVolume:6
u0_a38 16522 16265 1348552 89960 0 0 S com.android.systemui
u0_a56 16765 16265 1343904 94124 0 0 S com.google.android.inputmethod.latin
u0_a42 16783 16265 1302956 67868 0 0 S com.google.android.tv.remote.service
"""

GET_PROPERTIES_DICT_GOOGLE_TV = {'screen_on': True,
'awake': True,
'audio_state': constants.STATE_PAUSED,
'wake_lock_size': 4,
'current_app': 'com.google.android.youtube.tv',
'media_session_state': 3,
'audio_output_device': 'hdmi',
'is_volume_muted': False,
'volume': 25,
'running_apps': ['com.android.systemui', 'com.google.android.inputmethod.latin', 'com.google.android.tv.remote.service']}

# https://community.home-assistant.io/t/testers-needed-custom-state-detection-rules-for-android-tv-fire-tv/129493/6?u=jefflirion
STATE_DETECTION_RULES_PLEX = {'com.plexapp.android': [{'playing': {'media_session_state': 3,
'wake_lock_size': 3}},
Expand Down Expand Up @@ -627,6 +659,10 @@ def test_get_properties(self):
properties = self.atv.get_properties_dict(get_running_apps=True, lazy=False)
self.assertEqual(properties, true_properties)

with patchers.patch_shell(GET_PROPERTIES_OUTPUT_GOOGLE_TV)[self.PATCH_KEY]:
properties = self.atv.get_properties_dict(get_running_apps=True, lazy=True)
self.assertEqual(properties, GET_PROPERTIES_DICT_GOOGLE_TV)

def test_update(self):
"""Check that the ``update`` method works correctly.
Expand Down
13 changes: 13 additions & 0 deletions tests/test_basetv_async.py
Expand Up @@ -58,6 +58,15 @@
'wifimac': None,
'ethmac': 'ab:cd:ef:gh:ij:kl'}

# Source: https://community.home-assistant.io/t/new-chromecast-w-android-tv-integration-only-showing-as-off-or-idle/234424/15
DEVICE_PROPERTIES_GOOGLE_TV = """Google
Chromecast
SERIALNO
10
link/ether ab:cd:ef:gh:ij:kl brd ff:ff:ff:ff:ff:ff
Device "eth0" does not exist.
"""

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}"

STATE_DETECTION_RULES1 = {'com.amazon.tv.launcher': ['off']}
Expand Down Expand Up @@ -330,6 +339,10 @@ async def test_get_device_properties(self):
device_properties = await self.btv.get_device_properties()
self.assertDictEqual({}, device_properties)

with async_patchers.patch_shell(DEVICE_PROPERTIES_GOOGLE_TV)[self.PATCH_KEY]:
device_properties = await self.btv.get_device_properties()
self.assertTrue(self.btv._is_google_tv)

@awaiter
async def test_awake(self):
"""Check that the ``awake`` property works correctly.
Expand Down
13 changes: 13 additions & 0 deletions tests/test_basetv_sync.py
Expand Up @@ -52,6 +52,15 @@
link/ether ab:cd:ef:gh:ij:kl brd ff:ff:ff:ff:ff:ff
"""

# Source: https://community.home-assistant.io/t/new-chromecast-w-android-tv-integration-only-showing-as-off-or-idle/234424/15
DEVICE_PROPERTIES_GOOGLE_TV = """Google
Chromecast
SERIALNO
10
link/ether ab:cd:ef:gh:ij:kl brd ff:ff:ff:ff:ff:ff
Device "eth0" does not exist.
"""

DEVICE_PROPERTIES_DICT3 = {'manufacturer': 'Not Amazon',
'model': 'AFTT',
'serialno': 'SERIALNO',
Expand Down Expand Up @@ -324,6 +333,10 @@ def test_get_device_properties(self):
device_properties = self.btv.get_device_properties()
self.assertDictEqual({}, device_properties)

with patchers.patch_shell(DEVICE_PROPERTIES_GOOGLE_TV)[self.PATCH_KEY]:
device_properties = self.btv.get_device_properties()
self.assertTrue(self.btv._is_google_tv)

def test_awake(self):
"""Check that the ``awake`` property works correctly.
Expand Down

0 comments on commit 2298502

Please sign in to comment.