From daddefdb39907d3b7b48a7b64a2b89b9897675ec Mon Sep 17 00:00:00 2001 From: Nortonko Date: Mon, 9 Oct 2023 19:55:04 +0200 Subject: [PATCH 1/2] add support for androidtv 12 & 13 --- androidtv/basetv/basetv.py | 63 ++++++++++++++++++++++++++++++++ androidtv/basetv/basetv_async.py | 2 +- androidtv/constants.py | 35 ++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) diff --git a/androidtv/basetv/basetv.py b/androidtv/basetv/basetv.py index 0f895890..a7a9ed73 100644 --- a/androidtv/basetv/basetv.py +++ b/androidtv/basetv/basetv.py @@ -131,6 +131,14 @@ def _cmd_audio_state(self): # Is this an Android 11 device? if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "11": return constants.CMD_AUDIO_STATE11 + + # Is this an Android 12 device? + if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "12": + return constants.CMD_AUDIO_STATE11 + + # Is this an Android 13 device? + if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "13": + return constants.CMD_AUDIO_STATE11 return constants.CMD_AUDIO_STATE def _cmd_current_app(self): @@ -157,6 +165,14 @@ def _cmd_current_app(self): if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "11": return constants.CMD_CURRENT_APP11 + # Is this an Android 12 device? + if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "12": + return constants.CMD_CURRENT_APP12 + + # Is this an Android 13 device? + if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "13": + return constants.CMD_CURRENT_APP13 + return constants.CMD_CURRENT_APP def _cmd_current_app_media_session_state(self): @@ -183,6 +199,14 @@ def _cmd_current_app_media_session_state(self): if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "11": return constants.CMD_CURRENT_APP_MEDIA_SESSION_STATE11 + # Is this an Android 11 device? + if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "12": + return constants.CMD_CURRENT_APP_MEDIA_SESSION_STATE12 + + # Is this an Android 13 device? + if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "13": + return constants.CMD_CURRENT_APP_MEDIA_SESSION_STATE13 + return constants.CMD_CURRENT_APP_MEDIA_SESSION_STATE def _cmd_hdmi_input(self): @@ -200,9 +224,40 @@ def _cmd_hdmi_input(self): # Is this an Android 11 device? if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "11": return constants.CMD_HDMI_INPUT11 + + # Is this an Android 12 device? + if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "12": + return constants.CMD_HDMI_INPUT11 + + # Is this an Android 13 device? + if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "13": + return constants.CMD_HDMI_INPUT11 return constants.CMD_HDMI_INPUT + def _cmd_volume_set(self): + """Get the command used to set volume for this device. + + Returns + ------- + str + The device-specific ADB shell command used to set volume + + """ + # Is this an Android 11 device? + if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "11": + return constants.CMD_VOLUME_SET_COMMAND12 + + # Is this an Android 12 device? + if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "12": + return constants.CMD_VOLUME_SET_COMMAND12 + + # Is this an Android 13 device? + if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "13": + return constants.CMD_VOLUME_SET_COMMAND13 + + return constants.CMD_VOLUME_SET_COMMAND + def _cmd_launch_app(self, app): """Get the command to launch the specified app for this device. @@ -234,6 +289,14 @@ def _cmd_launch_app(self, app): # Is this an Android 11 device? if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "11": return constants.CMD_LAUNCH_APP11.format(app) + + # Is this an Android 12 device? + if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "12": + return constants.CMD_LAUNCH_APP11.format(app) + + # Is this an Android 13 device? + if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "13": + return constants.CMD_LAUNCH_APP11.format(app) return constants.CMD_LAUNCH_APP.format(app) diff --git a/androidtv/basetv/basetv_async.py b/androidtv/basetv/basetv_async.py index e57198b7..b733fd87 100644 --- a/androidtv/basetv/basetv_async.py +++ b/androidtv/basetv/basetv_async.py @@ -830,7 +830,7 @@ async def set_volume_level(self, volume_level): new_volume = int(min(max(round(self.max_volume * volume_level), 0.0), self.max_volume)) - await self._adb.shell("media volume --show --stream 3 --set {}".format(new_volume)) + await self._adb.shell(self._cmd_volume_set().format(new_volume)) # return the new volume level return new_volume / self.max_volume diff --git a/androidtv/constants.py b/androidtv/constants.py index 320a0df1..81ba5028 100644 --- a/androidtv/constants.py +++ b/androidtv/constants.py @@ -99,6 +99,15 @@ class DeviceEnum(IntEnum): "CURRENT_APP=$(dumpsys window windows | grep -E -m 1 'mInputMethod(Input)?Target') && " + CMD_PARSE_CURRENT_APP11 ) +#: Assign focused application identifier to ``CURRENT_APP`` variable for an Android 12 device +CMD_DEFINE_CURRENT_APP_VARIABLE12 = ( + "CURRENT_APP=$(dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp|mObscuringWindow') && " + CMD_PARSE_CURRENT_APP11 +) + +#: Assign focused application identifier to ``CURRENT_APP`` variable for an Android 13 device +CMD_DEFINE_CURRENT_APP_VARIABLE13 = ( + "CURRENT_APP=$(dumpsys window windows | grep -E -m 1 'imeLayeringTarget|imeInputTarget|imeControlTarget') && " + CMD_PARSE_CURRENT_APP11 +) #: Output identifier for current/focused application CMD_CURRENT_APP = CMD_DEFINE_CURRENT_APP_VARIABLE + " && echo $CURRENT_APP" @@ -106,6 +115,12 @@ class DeviceEnum(IntEnum): #: Output identifier for current/focused application for an Android 11 device CMD_CURRENT_APP11 = CMD_DEFINE_CURRENT_APP_VARIABLE11 + " && echo $CURRENT_APP" +#: Output identifier for current/focused application for an Android 12 device +CMD_CURRENT_APP12 = CMD_DEFINE_CURRENT_APP_VARIABLE12 + " && echo $CURRENT_APP" + +#: Output identifier for current/focused application for an Android 13 device +CMD_CURRENT_APP13 = CMD_DEFINE_CURRENT_APP_VARIABLE13 + " && echo $CURRENT_APP" + #: Assign focused application identifier to ``CURRENT_APP`` variable (for a Google TV device) CMD_DEFINE_CURRENT_APP_VARIABLE_GOOGLE_TV = ( "CURRENT_APP=$(dumpsys activity a . | grep mResumedActivity) && " + CMD_PARSE_CURRENT_APP @@ -114,6 +129,21 @@ class DeviceEnum(IntEnum): #: Output identifier for current/focused application (for a Google TV device) CMD_CURRENT_APP_GOOGLE_TV = CMD_DEFINE_CURRENT_APP_VARIABLE_GOOGLE_TV + " && echo $CURRENT_APP" +#: set volume +CMD_VOLUME_SET_COMMAND = ( + "media volume --show --stream 3 --set {}" +) + +#: set volume for an Android 12 device +CMD_VOLUME_SET_COMMAND12 = ( + "cmd media_session volume --show --stream 3 --set {}" +) + +#: set volume for an Android 13 device +CMD_VOLUME_SET_COMMAND13 = ( + "cmd media_session volume --show --stream 3 --set {}" +) + #: Get the HDMI input CMD_HDMI_INPUT = ( "dumpsys activity starter | grep -E -o '(ExternalTv|HDMI)InputService/HW[0-9]' -m 1 | grep -o 'HW[0-9]'" @@ -164,6 +194,9 @@ class DeviceEnum(IntEnum): #: Determine the current app and get the state from ``dumpsys media_session`` for an Android 11 device CMD_CURRENT_APP_MEDIA_SESSION_STATE11 = CMD_CURRENT_APP11 + " && " + CMD_MEDIA_SESSION_STATE +#: Determine the current app and get the state from ``dumpsys media_session`` for an Android 13 device +CMD_CURRENT_APP_MEDIA_SESSION_STATE13 = CMD_CURRENT_APP13 + " && " + CMD_MEDIA_SESSION_STATE + #: Determine the current app and get the state from ``dumpsys media_session`` for a Google TV device CMD_CURRENT_APP_MEDIA_SESSION_STATE_GOOGLE_TV = CMD_CURRENT_APP_GOOGLE_TV + " && " + CMD_MEDIA_SESSION_STATE @@ -484,6 +517,7 @@ class DeviceEnum(IntEnum): APP_VEVO = "com.vevo.tv" APP_VH1 = "com.mtvn.vh1android" APP_VIMEO = "com.vimeo.android.videoapp" +APP_VIKI = "com.viki.android" APP_VLC = "org.videolan.vlc" APP_VOYO = "com.phonegap.voyo" APP_VRV = "com.ellation.vrv" @@ -591,6 +625,7 @@ class DeviceEnum(IntEnum): APP_VEVO: "Vevo", APP_VH1: "VH1", APP_VIMEO: "Vimeo", + APP_VIKI: "Rakuten Viki", APP_VLC: "VLC", APP_VOYO: "VOYO", APP_VRV: "VRV", From 7e569ed336be00809dbdabb757c64ee27ce1cbb0 Mon Sep 17 00:00:00 2001 From: Nortonko Date: Mon, 9 Oct 2023 20:16:08 +0200 Subject: [PATCH 2/2] reformated code by black formater --- androidtv/basetv/basetv.py | 231 +++++++++++++++++++++++++++++-------- androidtv/constants.py | 93 ++++++++++----- 2 files changed, 242 insertions(+), 82 deletions(-) diff --git a/androidtv/basetv/basetv.py b/androidtv/basetv/basetv.py index a7a9ed73..ee875036 100644 --- a/androidtv/basetv/basetv.py +++ b/androidtv/basetv/basetv.py @@ -69,7 +69,14 @@ class BaseTV(object): # pylint: disable=too-few-public-methods DEVICE_ENUM = constants.DeviceEnum.BASETV def __init__( - self, adb, host, port=5555, adbkey="", adb_server_ip="", adb_server_port=5037, state_detection_rules=None + self, + adb, + host, + port=5555, + adbkey="", + adb_server_ip="", + adb_server_port=5037, + state_detection_rules=None, ): self._adb = adb self.host = host @@ -85,7 +92,11 @@ def __init__( if self._state_detection_rules: for app_id, rules in self._state_detection_rules.items(): if not isinstance(app_id, str): - raise TypeError("{0} is of type {1}, not str".format(app_id, type(app_id).__name__)) + raise TypeError( + "{0} is of type {1}, not str".format( + app_id, type(app_id).__name__ + ) + ) state_detection_rules_validator(rules) # the max volume level (determined when first getting the volume level) @@ -129,15 +140,24 @@ def _cmd_audio_state(self): return self._custom_commands[constants.CUSTOM_AUDIO_STATE] # Is this an Android 11 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "11": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "11" + ): return constants.CMD_AUDIO_STATE11 - + # Is this an Android 12 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "12": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "12" + ): return constants.CMD_AUDIO_STATE11 - + # Is this an Android 13 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "13": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "13" + ): return constants.CMD_AUDIO_STATE11 return constants.CMD_AUDIO_STATE @@ -162,15 +182,24 @@ def _cmd_current_app(self): return constants.CMD_CURRENT_APP_GOOGLE_TV # Is this an Android 11 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "11": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "11" + ): return constants.CMD_CURRENT_APP11 # Is this an Android 12 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "12": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "12" + ): return constants.CMD_CURRENT_APP12 - + # Is this an Android 13 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "13": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "13" + ): return constants.CMD_CURRENT_APP13 return constants.CMD_CURRENT_APP @@ -185,7 +214,9 @@ def _cmd_current_app_media_session_state(self): """ if constants.CUSTOM_CURRENT_APP_MEDIA_SESSION_STATE in self._custom_commands: - return self._custom_commands[constants.CUSTOM_CURRENT_APP_MEDIA_SESSION_STATE] + return self._custom_commands[ + constants.CUSTOM_CURRENT_APP_MEDIA_SESSION_STATE + ] # Is this a Google Chromecast Android TV? if ( @@ -196,15 +227,24 @@ def _cmd_current_app_media_session_state(self): return constants.CMD_CURRENT_APP_MEDIA_SESSION_STATE_GOOGLE_TV # Is this an Android 11 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "11": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "11" + ): return constants.CMD_CURRENT_APP_MEDIA_SESSION_STATE11 # Is this an Android 11 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "12": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "12" + ): return constants.CMD_CURRENT_APP_MEDIA_SESSION_STATE12 - + # Is this an Android 13 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "13": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "13" + ): return constants.CMD_CURRENT_APP_MEDIA_SESSION_STATE13 return constants.CMD_CURRENT_APP_MEDIA_SESSION_STATE @@ -222,15 +262,24 @@ def _cmd_hdmi_input(self): return self._custom_commands[constants.CUSTOM_HDMI_INPUT] # Is this an Android 11 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "11": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "11" + ): return constants.CMD_HDMI_INPUT11 - + # Is this an Android 12 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "12": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "12" + ): return constants.CMD_HDMI_INPUT11 - + # Is this an Android 13 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "13": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "13" + ): return constants.CMD_HDMI_INPUT11 return constants.CMD_HDMI_INPUT @@ -245,19 +294,28 @@ def _cmd_volume_set(self): """ # Is this an Android 11 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "11": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "11" + ): return constants.CMD_VOLUME_SET_COMMAND12 # Is this an Android 12 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "12": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "12" + ): return constants.CMD_VOLUME_SET_COMMAND12 - + # Is this an Android 13 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "13": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "13" + ): return constants.CMD_VOLUME_SET_COMMAND13 return constants.CMD_VOLUME_SET_COMMAND - + def _cmd_launch_app(self, app): """Get the command to launch the specified app for this device. @@ -287,15 +345,24 @@ def _cmd_launch_app(self, app): return constants.CMD_LAUNCH_APP_FIRETV.format(app) # Is this an Android 11 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "11": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "11" + ): return constants.CMD_LAUNCH_APP11.format(app) - + # Is this an Android 12 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "12": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "12" + ): return constants.CMD_LAUNCH_APP11.format(app) - + # Is this an Android 13 device? - if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "13": + if ( + self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV + and self.device_properties.get("sw_version", "") == "13" + ): return constants.CMD_LAUNCH_APP11.format(app) return constants.CMD_LAUNCH_APP.format(app) @@ -402,7 +469,12 @@ def _parse_device_properties(self, properties): ``'serialno'``, ``'manufacturer'``, ``'model'``, and ``'sw_version'`` """ - _LOGGER.debug("%s:%d `get_device_properties` response: %s", self.host, self.port, properties) + _LOGGER.debug( + "%s:%d `get_device_properties` response: %s", + self.host, + self.port, + properties, + ) if not properties: self.device_properties = {} @@ -416,7 +488,12 @@ def _parse_device_properties(self, properties): manufacturer, model, serialno, version = lines if not serialno.strip(): - _LOGGER.warning("Could not obtain serialno for %s:%d, got: '%s'", self.host, self.port, serialno) + _LOGGER.warning( + "Could not obtain serialno for %s:%d, got: '%s'", + self.host, + self.port, + serialno, + ) serialno = None self.device_properties = { @@ -456,7 +533,11 @@ def _parse_mac_address(mac_response): # # # ======================================================================= # def _custom_state_detection( - self, current_app=None, media_session_state=None, wake_lock_size=None, audio_state=None + self, + current_app=None, + media_session_state=None, + wake_lock_size=None, + audio_state=None, ): """Use the rules in ``self._state_detection_rules`` to determine the state. @@ -477,7 +558,11 @@ def _custom_state_detection( The state, if it could be determined using the rules in ``self._state_detection_rules``; otherwise, ``None`` """ - if not self._state_detection_rules or current_app is None or current_app not in self._state_detection_rules: + if ( + not self._state_detection_rules + or current_app is None + or current_app not in self._state_detection_rules + ): return None rules = self._state_detection_rules[current_app] @@ -511,7 +596,9 @@ def _custom_state_detection( return None @staticmethod - def _conditions_are_true(conditions, media_session_state=None, wake_lock_size=None, audio_state=None): + def _conditions_are_true( + conditions, media_session_state=None, wake_lock_size=None, audio_state=None + ): """Check whether the conditions in ``conditions`` are true. Parameters @@ -573,7 +660,9 @@ def _audio_output_device(stream_music): if not stream_music: return None - matches = re.findall(constants.DEVICE_REGEX_PATTERN, stream_music, re.DOTALL | re.MULTILINE) + matches = re.findall( + constants.DEVICE_REGEX_PATTERN, stream_music, re.DOTALL | re.MULTILINE + ) if matches: return matches[0] @@ -617,12 +706,18 @@ def _current_app(current_app_response): The current app, or ``None`` if it could not be determined """ - if not current_app_response or "=" in current_app_response or "{" in current_app_response: + if ( + not current_app_response + or "=" in current_app_response + or "{" in current_app_response + ): return None return current_app_response - def _current_app_media_session_state(self, current_app_media_session_state_response): + def _current_app_media_session_state( + self, current_app_media_session_state_response + ): """Get the current app and the media session state properties from the output of `androidtv.basetv.basetv.BaseTV._cmd_current_app_media_session_state`. Parameters @@ -646,7 +741,9 @@ def _current_app_media_session_state(self, current_app_media_session_state_respo current_app = self._current_app(lines[0].strip()) if len(lines) > 1: - matches = constants.REGEX_MEDIA_SESSION_STATE.search(current_app_media_session_state_response) + matches = constants.REGEX_MEDIA_SESSION_STATE.search( + current_app_media_session_state_response + ) if matches: return current_app, int(matches.group("state")) @@ -667,7 +764,9 @@ def _get_hdmi_input(hdmi_response): The HDMI input, or ``None`` if it could not be determined """ - return hdmi_response.strip() if hdmi_response and hdmi_response.strip() else None + return ( + hdmi_response.strip() if hdmi_response and hdmi_response.strip() else None + ) @staticmethod def _get_installed_apps(installed_apps_response): @@ -686,7 +785,9 @@ def _get_installed_apps(installed_apps_response): """ if installed_apps_response is not None: return [ - line.strip().rsplit("package:", 1)[-1] for line in installed_apps_response.splitlines() if line.strip() + line.strip().rsplit("package:", 1)[-1] + for line in installed_apps_response.splitlines() + if line.strip() ] return None @@ -709,7 +810,9 @@ def _is_volume_muted(stream_music): if not stream_music: return None - matches = re.findall(constants.MUTED_REGEX_PATTERN, stream_music, re.DOTALL | re.MULTILINE) + matches = re.findall( + constants.MUTED_REGEX_PATTERN, stream_music, re.DOTALL | re.MULTILINE + ) if matches: return matches[0] == "true" @@ -733,7 +836,11 @@ def _parse_stream_music(stream_music_raw): if not stream_music_raw: return None - matches = re.findall(constants.STREAM_MUSIC_REGEX_PATTERN, stream_music_raw, re.DOTALL | re.MULTILINE) + matches = re.findall( + constants.STREAM_MUSIC_REGEX_PATTERN, + stream_music_raw, + re.DOTALL | re.MULTILINE, + ) if matches: return matches[0] @@ -755,7 +862,11 @@ def _running_apps(running_apps_response): """ if running_apps_response: - return [line.strip().rsplit(" ", 1)[-1] for line in running_apps_response.splitlines() if line.strip()] + return [ + line.strip().rsplit(" ", 1)[-1] + for line in running_apps_response.splitlines() + if line.strip() + ] return None @@ -810,7 +921,11 @@ def _volume(self, stream_music, audio_output_device): return None if not self.max_volume: - max_volume_matches = re.findall(constants.MAX_VOLUME_REGEX_PATTERN, stream_music, re.DOTALL | re.MULTILINE) + max_volume_matches = re.findall( + constants.MAX_VOLUME_REGEX_PATTERN, + stream_music, + re.DOTALL | re.MULTILINE, + ) if max_volume_matches: self.max_volume = float(max_volume_matches[0]) @@ -818,7 +933,9 @@ def _volume(self, stream_music, audio_output_device): return None volume_matches = re.findall( - audio_output_device + constants.VOLUME_REGEX_PATTERN, stream_music, re.DOTALL | re.MULTILINE + audio_output_device + constants.VOLUME_REGEX_PATTERN, + stream_music, + re.DOTALL | re.MULTILINE, ) if volume_matches: return int(volume_matches[0]) @@ -860,7 +977,9 @@ def _wake_lock_size(wake_lock_size_response): """ if wake_lock_size_response: - wake_lock_size_matches = constants.REGEX_WAKE_LOCK_SIZE.search(wake_lock_size_response) + wake_lock_size_matches = constants.REGEX_WAKE_LOCK_SIZE.search( + wake_lock_size_response + ) if wake_lock_size_matches: return int(wake_lock_size_matches.group("size")) @@ -943,7 +1062,11 @@ def state_detection_rules_validator(rules, exc=KeyError): for state, conditions in rule.items(): # The keys of the dictionary must be valid states if state not in constants.VALID_STATES: - raise exc("'{0}' is not a valid state for the 'state_detection_rules' parameter".format(state)) + raise exc( + "'{0}' is not a valid state for the 'state_detection_rules' parameter".format( + state + ) + ) # The values of the dictionary must be dictionaries if not isinstance(conditions, dict): @@ -956,13 +1079,19 @@ def state_detection_rules_validator(rules, exc=KeyError): for prop, value in conditions.items(): # The keys of the dictionary must be valid properties that can be checked if prop not in constants.VALID_PROPERTIES: - raise exc("Invalid property '{0}' is not in {1}".format(prop, constants.VALID_PROPERTIES)) + raise exc( + "Invalid property '{0}' is not in {1}".format( + prop, constants.VALID_PROPERTIES + ) + ) # Make sure the value is of the right type if not isinstance(value, constants.VALID_PROPERTIES_TYPES[prop]): raise exc( "Conditional value for property '{0}' must be of type {1}, not {2}".format( - prop, constants.VALID_PROPERTIES_TYPES[prop].__name__, type(value).__name__ + prop, + constants.VALID_PROPERTIES_TYPES[prop].__name__, + type(value).__name__, ) ) diff --git a/androidtv/constants.py b/androidtv/constants.py index 81ba5028..107341c9 100644 --- a/androidtv/constants.py +++ b/androidtv/constants.py @@ -88,25 +88,31 @@ class DeviceEnum(IntEnum): CMD_PARSE_CURRENT_APP = "CURRENT_APP=${CURRENT_APP#*ActivityRecord{* * } && CURRENT_APP=${CURRENT_APP#*{* * } && CURRENT_APP=${CURRENT_APP%%/*} && CURRENT_APP=${CURRENT_APP%\\}*}" #: Parse current application for an Android 11 device -CMD_PARSE_CURRENT_APP11 = "CURRENT_APP=${CURRENT_APP%%/*} && CURRENT_APP=${CURRENT_APP##* }" +CMD_PARSE_CURRENT_APP11 = ( + "CURRENT_APP=${CURRENT_APP%%/*} && CURRENT_APP=${CURRENT_APP##* }" +) #: Assign focused application identifier to ``CURRENT_APP`` variable CMD_DEFINE_CURRENT_APP_VARIABLE = ( - "CURRENT_APP=$(dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp') && " + CMD_PARSE_CURRENT_APP + "CURRENT_APP=$(dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp') && " + + CMD_PARSE_CURRENT_APP ) #: Assign focused application identifier to ``CURRENT_APP`` variable for an Android 11 device CMD_DEFINE_CURRENT_APP_VARIABLE11 = ( - "CURRENT_APP=$(dumpsys window windows | grep -E -m 1 'mInputMethod(Input)?Target') && " + CMD_PARSE_CURRENT_APP11 + "CURRENT_APP=$(dumpsys window windows | grep -E -m 1 'mInputMethod(Input)?Target') && " + + CMD_PARSE_CURRENT_APP11 ) #: Assign focused application identifier to ``CURRENT_APP`` variable for an Android 12 device CMD_DEFINE_CURRENT_APP_VARIABLE12 = ( - "CURRENT_APP=$(dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp|mObscuringWindow') && " + CMD_PARSE_CURRENT_APP11 + "CURRENT_APP=$(dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp|mObscuringWindow') && " + + CMD_PARSE_CURRENT_APP11 ) #: Assign focused application identifier to ``CURRENT_APP`` variable for an Android 13 device CMD_DEFINE_CURRENT_APP_VARIABLE13 = ( - "CURRENT_APP=$(dumpsys window windows | grep -E -m 1 'imeLayeringTarget|imeInputTarget|imeControlTarget') && " + CMD_PARSE_CURRENT_APP11 + "CURRENT_APP=$(dumpsys window windows | grep -E -m 1 'imeLayeringTarget|imeInputTarget|imeControlTarget') && " + + CMD_PARSE_CURRENT_APP11 ) #: Output identifier for current/focused application @@ -123,31 +129,26 @@ class DeviceEnum(IntEnum): #: Assign focused application identifier to ``CURRENT_APP`` variable (for a Google TV device) CMD_DEFINE_CURRENT_APP_VARIABLE_GOOGLE_TV = ( - "CURRENT_APP=$(dumpsys activity a . | grep mResumedActivity) && " + CMD_PARSE_CURRENT_APP + "CURRENT_APP=$(dumpsys activity a . | grep mResumedActivity) && " + + CMD_PARSE_CURRENT_APP ) #: Output identifier for current/focused application (for a Google TV device) -CMD_CURRENT_APP_GOOGLE_TV = CMD_DEFINE_CURRENT_APP_VARIABLE_GOOGLE_TV + " && echo $CURRENT_APP" +CMD_CURRENT_APP_GOOGLE_TV = ( + CMD_DEFINE_CURRENT_APP_VARIABLE_GOOGLE_TV + " && echo $CURRENT_APP" +) #: set volume -CMD_VOLUME_SET_COMMAND = ( - "media volume --show --stream 3 --set {}" -) +CMD_VOLUME_SET_COMMAND = "media volume --show --stream 3 --set {}" #: set volume for an Android 12 device -CMD_VOLUME_SET_COMMAND12 = ( - "cmd media_session volume --show --stream 3 --set {}" -) +CMD_VOLUME_SET_COMMAND12 = "cmd media_session volume --show --stream 3 --set {}" #: set volume for an Android 13 device -CMD_VOLUME_SET_COMMAND13 = ( - "cmd media_session volume --show --stream 3 --set {}" -) +CMD_VOLUME_SET_COMMAND13 = "cmd media_session volume --show --stream 3 --set {}" #: Get the HDMI input -CMD_HDMI_INPUT = ( - "dumpsys activity starter | grep -E -o '(ExternalTv|HDMI)InputService/HW[0-9]' -m 1 | grep -o 'HW[0-9]'" -) +CMD_HDMI_INPUT = "dumpsys activity starter | grep -E -o '(ExternalTv|HDMI)InputService/HW[0-9]' -m 1 | grep -o 'HW[0-9]'" #: Get the HDMI input for an Android 11 device CMD_HDMI_INPUT11 = ( @@ -157,32 +158,44 @@ class DeviceEnum(IntEnum): #: Launch an app if it is not already the current app (assumes the variable ``CURRENT_APP`` has already been set) CMD_LAUNCH_APP_CONDITION = ( - "if [ $CURRENT_APP != '{0}' ]; then monkey -p {0} -c " + INTENT_LAUNCH + " --pct-syskeys 0 1; fi" + "if [ $CURRENT_APP != '{0}' ]; then monkey -p {0} -c " + + INTENT_LAUNCH + + " --pct-syskeys 0 1; fi" ) #: Launch an app if it is not already the current app (assumes the variable ``CURRENT_APP`` has already been set) on a Fire TV CMD_LAUNCH_APP_CONDITION_FIRETV = ( - "if [ $CURRENT_APP != '{0}' ]; then monkey -p {0} -c " + INTENT_LAUNCH_FIRETV + " --pct-syskeys 0 1; fi" + "if [ $CURRENT_APP != '{0}' ]; then monkey -p {0} -c " + + INTENT_LAUNCH_FIRETV + + " --pct-syskeys 0 1; fi" ) #: Launch an app if it is not already the current app CMD_LAUNCH_APP = ( - CMD_DEFINE_CURRENT_APP_VARIABLE.replace("{", "{{").replace("}", "}}") + " && " + CMD_LAUNCH_APP_CONDITION + CMD_DEFINE_CURRENT_APP_VARIABLE.replace("{", "{{").replace("}", "}}") + + " && " + + CMD_LAUNCH_APP_CONDITION ) #: Launch an app if it is not already the current app on an Android 11 device CMD_LAUNCH_APP11 = ( - CMD_DEFINE_CURRENT_APP_VARIABLE11.replace("{", "{{").replace("}", "}}") + " && " + CMD_LAUNCH_APP_CONDITION + CMD_DEFINE_CURRENT_APP_VARIABLE11.replace("{", "{{").replace("}", "}}") + + " && " + + CMD_LAUNCH_APP_CONDITION ) #: Launch an app on a Fire TV device CMD_LAUNCH_APP_FIRETV = ( - CMD_DEFINE_CURRENT_APP_VARIABLE.replace("{", "{{").replace("}", "}}") + " && " + CMD_LAUNCH_APP_CONDITION_FIRETV + CMD_DEFINE_CURRENT_APP_VARIABLE.replace("{", "{{").replace("}", "}}") + + " && " + + CMD_LAUNCH_APP_CONDITION_FIRETV ) #: Launch an app on a Google TV device CMD_LAUNCH_APP_GOOGLE_TV = ( - CMD_DEFINE_CURRENT_APP_VARIABLE_GOOGLE_TV.replace("{", "{{").replace("}", "}}") + " && " + CMD_LAUNCH_APP_CONDITION + CMD_DEFINE_CURRENT_APP_VARIABLE_GOOGLE_TV.replace("{", "{{").replace("}", "}}") + + " && " + + CMD_LAUNCH_APP_CONDITION ) #: Get the state from ``dumpsys media_session``; this assumes that the variable ``CURRENT_APP`` has been defined @@ -192,13 +205,19 @@ class DeviceEnum(IntEnum): CMD_CURRENT_APP_MEDIA_SESSION_STATE = CMD_CURRENT_APP + " && " + CMD_MEDIA_SESSION_STATE #: Determine the current app and get the state from ``dumpsys media_session`` for an Android 11 device -CMD_CURRENT_APP_MEDIA_SESSION_STATE11 = CMD_CURRENT_APP11 + " && " + CMD_MEDIA_SESSION_STATE +CMD_CURRENT_APP_MEDIA_SESSION_STATE11 = ( + CMD_CURRENT_APP11 + " && " + CMD_MEDIA_SESSION_STATE +) #: Determine the current app and get the state from ``dumpsys media_session`` for an Android 13 device -CMD_CURRENT_APP_MEDIA_SESSION_STATE13 = CMD_CURRENT_APP13 + " && " + CMD_MEDIA_SESSION_STATE +CMD_CURRENT_APP_MEDIA_SESSION_STATE13 = ( + CMD_CURRENT_APP13 + " && " + CMD_MEDIA_SESSION_STATE +) #: Determine the current app and get the state from ``dumpsys media_session`` for a Google TV device -CMD_CURRENT_APP_MEDIA_SESSION_STATE_GOOGLE_TV = CMD_CURRENT_APP_GOOGLE_TV + " && " + CMD_MEDIA_SESSION_STATE +CMD_CURRENT_APP_MEDIA_SESSION_STATE_GOOGLE_TV = ( + CMD_CURRENT_APP_GOOGLE_TV + " && " + CMD_MEDIA_SESSION_STATE +) #: Get the running apps for an Android TV device CMD_RUNNING_APPS_ANDROIDTV = "ps -A | grep u0_a" @@ -232,7 +251,13 @@ class DeviceEnum(IntEnum): #: Determine if the device is on, the screen is on, and get the wake lock size CMD_SCREEN_ON_AWAKE_WAKE_LOCK_SIZE = ( - CMD_SCREEN_ON + CMD_SUCCESS1_FAILURE0 + " && " + CMD_AWAKE + CMD_SUCCESS1_FAILURE0 + " && " + CMD_WAKE_LOCK_SIZE + CMD_SCREEN_ON + + CMD_SUCCESS1_FAILURE0 + + " && " + + CMD_AWAKE + + CMD_SUCCESS1_FAILURE0 + + " && " + + CMD_WAKE_LOCK_SIZE ) # `getprop` commands @@ -246,7 +271,9 @@ class DeviceEnum(IntEnum): CMD_MAC_ETH0 = "ip addr show eth0 | grep -m 1 ether" #: The command used for getting the device properties -CMD_DEVICE_PROPERTIES = CMD_MANUFACTURER + " && " + CMD_MODEL + " && " + CMD_SERIALNO + " && " + CMD_VERSION +CMD_DEVICE_PROPERTIES = ( + CMD_MANUFACTURER + " && " + CMD_MODEL + " && " + CMD_SERIALNO + " && " + CMD_VERSION +) # ADB key event codes @@ -414,7 +441,11 @@ class DeviceEnum(IntEnum): VALID_PROPERTIES = VALID_STATE_PROPERTIES + ("wake_lock_size",) #: The required type for each entry in :py:const:`VALID_PROPERTIES` (used by :func:`~androidtv.basetv.state_detection_rules_validator`) -VALID_PROPERTIES_TYPES = {"audio_state": str, "media_session_state": int, "wake_lock_size": int} +VALID_PROPERTIES_TYPES = { + "audio_state": str, + "media_session_state": int, + "wake_lock_size": int, +} # https://developer.android.com/reference/android/media/session/PlaybackState.html #: States for the :attr:`~androidtv.basetv.basetv.BaseTV.media_session_state` property