Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions androidtv/basetv/basetv.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,14 @@ def _cmd_current_app(self):
):
return constants.CMD_CURRENT_APP_ASKEY_STI6130

# Is this an Askey ADT-3 Device (e.g. HTC MagicubOS projectors)?
if (
self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV
and "askey" in self.device_properties.get("manufacturer", "")
and "adt3" in self.device_properties.get("product_id", "")
):
return constants.CMD_CURRENT_APP_ASKEY_ADT3

# Is this an Android 11 device?
if self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV and self.device_properties.get("sw_version", "") == "11":
return constants.CMD_CURRENT_APP11
Expand Down Expand Up @@ -210,6 +218,14 @@ def _cmd_current_app_media_session_state(self):
):
return constants.CMD_CURRENT_APP_MEDIA_SESSION_STATE_ASKEY_STI6130

# Is this an Askey ADT-3 Device (e.g. HTC MagicubOS projectors)?
if (
self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV
and "askey" in self.device_properties.get("manufacturer", "")
and "adt3" in self.device_properties.get("product_id", "")
):
return constants.CMD_CURRENT_APP_MEDIA_SESSION_STATE_ASKEY_ADT3

# Is this a Google Chromecast Android TV?
if (
self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV
Expand Down Expand Up @@ -311,6 +327,14 @@ def _cmd_launch_app(self, app):
if self.DEVICE_ENUM == constants.DeviceEnum.FIRETV:
return constants.CMD_LAUNCH_APP_FIRETV.format(app)

# Is this an Askey ADT-3 Device (e.g. HTC MagicubOS projectors)?
if (
self.DEVICE_ENUM == constants.DeviceEnum.ANDROIDTV
and "askey" in self.device_properties.get("manufacturer", "")
and "adt3" in self.device_properties.get("product_id", "")
):
return constants.CMD_LAUNCH_APP_ASKEY_ADT3.format(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)
Expand Down
26 changes: 25 additions & 1 deletion androidtv/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,17 @@ class DeviceEnum(IntEnum):
#: Output identifier for current/focused application (for a Askey STI6130)
CMD_CURRENT_APP_ASKEY_STI6130 = CMD_DEFINE_CURRENT_APP_VARIABLE_ASKEY_STI6130 + " && echo $CURRENT_APP "

#: Assign focused application identifier to ``CURRENT_APP`` variable (for an Askey ADT-3, e.g. HTC MagicubOS projectors)
#: On this device (Android 14, sdk 34), ``dumpsys window windows`` no longer includes ``mCurrentFocus``/
#: ``mFocusedApp``/``mObscuringWindow``/``imeLayeringTarget`` etc. Those fields are only present in the
#: unfiltered ``dumpsys window`` output.
CMD_DEFINE_CURRENT_APP_VARIABLE_ASKEY_ADT3 = (
"CURRENT_APP=$(dumpsys window | grep -E 'mCurrentFocus|mFocusedApp|mObscuringWindow') && " + CMD_PARSE_CURRENT_APP11
)

#: Output identifier for current/focused application (for an Askey ADT-3)
CMD_CURRENT_APP_ASKEY_ADT3 = CMD_DEFINE_CURRENT_APP_VARIABLE_ASKEY_ADT3 + " && echo $CURRENT_APP"


#: Assign focused application identifier to ``CURRENT_APP`` variable (for a Google TV device)
CMD_DEFINE_CURRENT_APP_VARIABLE_GOOGLE_TV = (
Expand Down Expand Up @@ -188,6 +199,11 @@ class DeviceEnum(IntEnum):
CMD_DEFINE_CURRENT_APP_VARIABLE13.replace("{", "{{").replace("}", "}}") + " && " + CMD_LAUNCH_APP_CONDITION
)

#: Launch an app if it is not already the current app on an Askey ADT-3 device
CMD_LAUNCH_APP_ASKEY_ADT3 = (
CMD_DEFINE_CURRENT_APP_VARIABLE_ASKEY_ADT3.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
Expand Down Expand Up @@ -216,6 +232,9 @@ class DeviceEnum(IntEnum):
#: Determine the current app and get the state from ``dumpsys media_session`` for a Askey STI6130
CMD_CURRENT_APP_MEDIA_SESSION_STATE_ASKEY_STI6130 = CMD_CURRENT_APP_ASKEY_STI6130 + " && " + CMD_MEDIA_SESSION_STATE

#: Determine the current app and get the state from ``dumpsys media_session`` for an Askey ADT-3
CMD_CURRENT_APP_MEDIA_SESSION_STATE_ASKEY_ADT3 = CMD_CURRENT_APP_ASKEY_ADT3 + " && " + 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

Expand All @@ -226,7 +245,12 @@ class DeviceEnum(IntEnum):
CMD_INSTALLED_APPS = "pm list packages"

#: Determine if the device is on
CMD_SCREEN_ON = "(dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true' || dumpsys display | grep -q 'mScreenState=ON')"
#: The ``dumpsys display`` fallback buffers output via command substitution before grepping it, rather than
#: piping directly into ``grep -q``. On devices with large ``dumpsys display`` output, ``grep -q`` closes its
#: end of the pipe as soon as it finds a match, and the still-writing ``dumpsys`` process can then fail with
#: "Failed to write while dumping service display: Broken pipe" -- text which gets prepended to the result
#: and corrupts callers (like ``screen_on_awake_wake_lock_size``) that parse it as a literal "1"/"0" string.
CMD_SCREEN_ON = "(dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true' || echo \"$(dumpsys display)\" | grep -q 'mScreenState=ON')"

#: Get the "STREAM_MUSIC" block from ``dumpsys audio``
CMD_STREAM_MUSIC = r"dumpsys audio | grep '\- STREAM_MUSIC:' -A 11"
Expand Down
1 change: 1 addition & 0 deletions tests/generate_test_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"CMD_DEFINE_CURRENT_APP_VARIABLE12",
"CMD_DEFINE_CURRENT_APP_VARIABLE13",
"CMD_DEFINE_CURRENT_APP_VARIABLE_ASKEY_STI6130",
"CMD_DEFINE_CURRENT_APP_VARIABLE_ASKEY_ADT3",
"CMD_DEFINE_CURRENT_APP_VARIABLE_GOOGLE_TV",
"CMD_LAUNCH_APP_CONDITION",
"CMD_LAUNCH_APP_CONDITION_FIRETV",
Expand Down
30 changes: 24 additions & 6 deletions tests/test_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ def test_constants(self):
constants.CMD_CURRENT_APP13,
r"CURRENT_APP=$(dumpsys window windows | grep -E -m 1 'imeLayeringTarget|imeInputTarget|imeControlTarget') && CURRENT_APP=${CURRENT_APP%%/*} && CURRENT_APP=${CURRENT_APP##* } && echo $CURRENT_APP",
)
# CMD_CURRENT_APP_ASKEY_ADT3
self.assertCommand(
constants.CMD_CURRENT_APP_ASKEY_ADT3,
r"CURRENT_APP=$(dumpsys window | grep -E 'mCurrentFocus|mFocusedApp|mObscuringWindow') && CURRENT_APP=${CURRENT_APP%%/*} && CURRENT_APP=${CURRENT_APP##* } && echo $CURRENT_APP",
)

# CMD_CURRENT_APP_ASKEY_STI6130
self.assertCommand(
constants.CMD_CURRENT_APP_ASKEY_STI6130,
Expand Down Expand Up @@ -135,6 +141,12 @@ def test_constants(self):
constants.CMD_CURRENT_APP_MEDIA_SESSION_STATE13,
r"CURRENT_APP=$(dumpsys window windows | grep -E -m 1 'imeLayeringTarget|imeInputTarget|imeControlTarget') && CURRENT_APP=${CURRENT_APP%%/*} && CURRENT_APP=${CURRENT_APP##* } && echo $CURRENT_APP && dumpsys media_session | grep -A 100 'Sessions Stack' | grep -A 100 $CURRENT_APP | grep -m 1 'state=PlaybackState {'",
)
# CMD_CURRENT_APP_MEDIA_SESSION_STATE_ASKEY_ADT3
self.assertCommand(
constants.CMD_CURRENT_APP_MEDIA_SESSION_STATE_ASKEY_ADT3,
r"CURRENT_APP=$(dumpsys window | grep -E 'mCurrentFocus|mFocusedApp|mObscuringWindow') && CURRENT_APP=${CURRENT_APP%%/*} && CURRENT_APP=${CURRENT_APP##* } && echo $CURRENT_APP && dumpsys media_session | grep -A 100 'Sessions Stack' | grep -A 100 $CURRENT_APP | grep -m 1 'state=PlaybackState {'",
)

# CMD_CURRENT_APP_MEDIA_SESSION_STATE_ASKEY_STI6130
self.assertCommand(
constants.CMD_CURRENT_APP_MEDIA_SESSION_STATE_ASKEY_STI6130,
Expand Down Expand Up @@ -192,6 +204,12 @@ def test_constants(self):
r"CURRENT_APP=$(dumpsys window windows | grep -E -m 1 'imeLayeringTarget|imeInputTarget|imeControlTarget') && CURRENT_APP=${{CURRENT_APP%%/*}} && CURRENT_APP=${{CURRENT_APP##* }} && if [ $CURRENT_APP != '{0}' ]; then monkey -p {0} -c android.intent.category.LEANBACK_LAUNCHER --pct-syskeys 0 1; fi",
)

# CMD_LAUNCH_APP_ASKEY_ADT3
self.assertCommand(
constants.CMD_LAUNCH_APP_ASKEY_ADT3,
r"CURRENT_APP=$(dumpsys window | grep -E 'mCurrentFocus|mFocusedApp|mObscuringWindow') && CURRENT_APP=${{CURRENT_APP%%/*}} && CURRENT_APP=${{CURRENT_APP##* }} && if [ $CURRENT_APP != '{0}' ]; then monkey -p {0} -c android.intent.category.LEANBACK_LAUNCHER --pct-syskeys 0 1; fi",
)

# CMD_LAUNCH_APP_FIRETV
self.assertCommand(
constants.CMD_LAUNCH_APP_FIRETV,
Expand Down Expand Up @@ -231,13 +249,13 @@ def test_constants(self):
# CMD_SCREEN_ON
self.assertCommand(
constants.CMD_SCREEN_ON,
r"(dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true' || dumpsys display | grep -q 'mScreenState=ON')",
r"""(dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true' || echo "$(dumpsys display)" | grep -q 'mScreenState=ON')""",
)

# CMD_SCREEN_ON_AWAKE_WAKE_LOCK_SIZE
self.assertCommand(
constants.CMD_SCREEN_ON_AWAKE_WAKE_LOCK_SIZE,
r"(dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true' || dumpsys display | grep -q 'mScreenState=ON') && echo -e '1\c' || echo -e '0\c' && dumpsys power | grep mWakefulness | grep -q Awake && echo -e '1\c' || echo -e '0\c' && dumpsys power | grep Locks | grep 'size='",
r"""(dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true' || echo "$(dumpsys display)" | grep -q 'mScreenState=ON') && echo -e '1\c' || echo -e '0\c' && dumpsys power | grep mWakefulness | grep -q Awake && echo -e '1\c' || echo -e '0\c' && dumpsys power | grep Locks | grep 'size='""",
)

# CMD_SERIALNO
Expand All @@ -249,25 +267,25 @@ def test_constants(self):
# CMD_TURN_OFF_ANDROIDTV
self.assertCommand(
constants.CMD_TURN_OFF_ANDROIDTV,
r"(dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true' || dumpsys display | grep -q 'mScreenState=ON') && input keyevent 26",
r"""(dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true' || echo "$(dumpsys display)" | grep -q 'mScreenState=ON') && input keyevent 26""",
)

# CMD_TURN_OFF_FIRETV
self.assertCommand(
constants.CMD_TURN_OFF_FIRETV,
r"(dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true' || dumpsys display | grep -q 'mScreenState=ON') && input keyevent 223",
r"""(dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true' || echo "$(dumpsys display)" | grep -q 'mScreenState=ON') && input keyevent 223""",
)

# CMD_TURN_ON_ANDROIDTV
self.assertCommand(
constants.CMD_TURN_ON_ANDROIDTV,
r"(dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true' || dumpsys display | grep -q 'mScreenState=ON') || input keyevent 26",
r"""(dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true' || echo "$(dumpsys display)" | grep -q 'mScreenState=ON') || input keyevent 26""",
)

# CMD_TURN_ON_FIRETV
self.assertCommand(
constants.CMD_TURN_ON_FIRETV,
r"(dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true' || dumpsys display | grep -q 'mScreenState=ON') || (input keyevent 26 && input keyevent 3)",
r"""(dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true' || echo "$(dumpsys display)" | grep -q 'mScreenState=ON') || (input keyevent 26 && input keyevent 3)""",
)

# CMD_VERSION
Expand Down
Loading