From d2bab8970d91fd7731958626e2b7f1280d33dd2d Mon Sep 17 00:00:00 2001 From: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com> Date: Wed, 14 Oct 2026 22:15:29 -0400 Subject: [PATCH] fix: droiddeckctl reaches variant-package builds (recover #842) (#854) fix: droiddeckctl reaches builds shipped under a variant package The provider authority and the start Activity's component were fixed to com.droiddeck.launcher, so droiddeckctl could not talk to the antutu, ludashi or pubg builds from tools/release/variants.txt. DROIDDECK_PACKAGE now picks the package; the Activity's class name stays the same in every variant. Co-authored-by: angelrenefm <17342133+angelrenefm@users.noreply.github.com> --- docs/agent-control.md | 2 ++ tools/droiddeckctl | 7 ++++--- tools/tests/test_droiddeckctl.py | 10 ++++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/docs/agent-control.md b/docs/agent-control.md index c7d16c2f9..f0eec7801 100644 --- a/docs/agent-control.md +++ b/docs/agent-control.md @@ -12,6 +12,8 @@ and reports every run. answers each command with JSON. It and the session-start Activity (`AgentStartActivity`) are in every build and require `android.permission.DUMP`, held by the ADB shell and privileged or explicitly granted callers. The provider checks the calling permission before decoding requests. + A build shipped under another package (`tools/release/variants.txt`) answers at + `content://.agent`: set `DROIDDECK_PACKAGE` to that package for `droiddeckctl`. - **The guest agent** `droiddeck-agent` runs inside every session (started by `droiddeck-session`). It runs commands with the session's own environment, publishes gamescope's focus, and talks to the Steam client's DevTools, which only accepts guest processes. The app and diff --git a/tools/droiddeckctl b/tools/droiddeckctl index 7c9f284b4..10f2cb682 100755 --- a/tools/droiddeckctl +++ b/tools/droiddeckctl @@ -18,8 +18,9 @@ sys.path.insert(0, str(Path(__file__).resolve().parent)) from adb_device import DeviceResolutionError, resolve_serial -AUTHORITY = "content://com.droiddeck.launcher.agent" -PACKAGE = "com.droiddeck.launcher" +# tools/release/variants.txt: the same app also ships as other packages (e.g. com.antutu.benchmark.full). +PACKAGE = os.environ.get("DROIDDECK_PACKAGE", "com.droiddeck.launcher") +AUTHORITY = f"content://{PACKAGE}.agent" STEAM_CLIENT_APP = 769 REQUEST_CAP = 256 * 1024 @@ -117,7 +118,7 @@ def start_agent_activity(adb: str, serial: str, request: dict) -> None: "start", "-W", "-n", - f"{PACKAGE}/.agent.AgentStartActivity", + f"{PACKAGE}/com.droiddeck.launcher.agent.AgentStartActivity", "--es", "request", encoded, diff --git a/tools/tests/test_droiddeckctl.py b/tools/tests/test_droiddeckctl.py index 02400452d..eda0c43dc 100644 --- a/tools/tests/test_droiddeckctl.py +++ b/tools/tests/test_droiddeckctl.py @@ -12,6 +12,7 @@ import sys import tempfile import textwrap import unittest +import unittest.mock TOOLS = Path(__file__).resolve().parents[1] sys.path.insert(0, str(TOOLS)) @@ -122,6 +123,15 @@ class DroiddeckctlTest(FakeAdbTest): self.assertEqual("INVALID_REQUEST", caught.exception.code) self.assertFalse(self.calls()) + def test_a_variant_package_is_reached_through_its_own_provider_and_activity(self): + with unittest.mock.patch.dict(os.environ, {"DROIDDECK_PACKAGE": "com.antutu.benchmark.full"}): + variant = load("droiddeckctl") + self.assertEqual("content://com.antutu.benchmark.full.agent", variant.AUTHORITY) + with self.assertRaises(variant.ControlError): # the fake adb does not answer `am start` + variant.start_agent_activity(str(self.adb), "fake-1", {"mode": "steam"}) + started = [e["args"] for e in self.calls() if e["args"][:3] == ["shell", "am", "start"]] + self.assertIn("com.antutu.benchmark.full/com.droiddeck.launcher.agent.AgentStartActivity", started[0]) + def test_state_passes_through_with_the_serial(self): self.configure({"state": state()}) code, out = self.run_ctl("state")