refactor(device): retire remaining single-device state
This commit is contained in:
commit
584bb2d09c
12 files changed
+175
-88
No files matched your search
@@ -404,9 +404,12 @@ class EmulatorManager:
|
||||
try:
|
||||
from artemis.core.diagnostics.engine import readiness_engine
|
||||
|
||||
readiness_engine.set_active_device_serial(detected_serial)
|
||||
# Focus the readiness report on the freshly booted
|
||||
# emulator; task routing still resolves its own
|
||||
# target from the request or the device pool.
|
||||
readiness_engine.set_probe_target_serial(detected_serial)
|
||||
except Exception as e:
|
||||
logger.debug(f"Failed to auto-select device serial: {e}")
|
||||
logger.debug(f"Failed to focus probes on the new emulator: {e}")
|
||||
return
|
||||
else:
|
||||
# Gradual progress visual indicator
|
||||
|
||||
@@ -52,7 +52,6 @@ class ReadinessEngine:
|
||||
|
||||
def __init__(self):
|
||||
self._probes: dict[str, BaseProbe] = {}
|
||||
self._active_device_serial: str | None = None
|
||||
self._python_probe = PythonRuntimeProbe()
|
||||
self._config_probe = SystemConfigProbe()
|
||||
self._toolchain_probe = ToolchainProbe()
|
||||
@@ -81,24 +80,19 @@ class ReadinessEngine:
|
||||
"""Remove a diagnostic probe."""
|
||||
self._probes.pop(probe_id, None)
|
||||
|
||||
def set_active_device_serial(self, serial: str | None) -> None:
|
||||
"""Set user-selected active target device serial."""
|
||||
self._active_device_serial = serial
|
||||
def set_probe_target_serial(self, serial: str | None) -> None:
|
||||
"""Set the diagnostics probes' preferred device serial.
|
||||
|
||||
This is a probe/report preference only (which device the readiness
|
||||
report highlights and verifies first). Task routing never reads it
|
||||
back: execution targets come from explicit request serials or the
|
||||
device pool. Pass None to clear the preference, e.g. after switching
|
||||
ADB server endpoints.
|
||||
"""
|
||||
self.invalidate_cache()
|
||||
if hasattr(self._adb_probe, "set_target_serial"):
|
||||
self._adb_probe.set_target_serial(serial)
|
||||
|
||||
def get_active_device_serial(self) -> str | None:
|
||||
"""Get currently selected active device serial."""
|
||||
if self._report_cache and self._report_cache.active_device:
|
||||
if self._report_cache.active_device.is_locked is False:
|
||||
return self._report_cache.active_device.serial
|
||||
if self._active_device_serial:
|
||||
return self._active_device_serial
|
||||
if self._report_cache and self._report_cache.active_device:
|
||||
return self._report_cache.active_device.serial
|
||||
return None
|
||||
|
||||
async def run_probe(self, probe_id: str) -> ProbeResult | None:
|
||||
"""Execute a single specific probe by ID."""
|
||||
probe = self._probes.get(probe_id)
|
||||
|
||||
@@ -150,7 +150,7 @@ def _configure_usb_stay_awake(device_id: str) -> str | None:
|
||||
|
||||
|
||||
def _discover_connected_device_ids() -> list[str]:
|
||||
"""Return the selected or all connected local Android devices."""
|
||||
"""Return the explicitly targeted device, or the connected devices Artemis manages."""
|
||||
if not _awake_enabled() or os.environ.get("ARTEMIS_CLOUD_MODE") == "1":
|
||||
return []
|
||||
|
||||
@@ -171,9 +171,18 @@ def _discover_connected_device_ids() -> list[str]:
|
||||
|
||||
if target:
|
||||
return [target] if target in serials else []
|
||||
# Artemis has a single-device execution policy. Do not modify unrelated
|
||||
# devices that happen to share the ADB server.
|
||||
return serials[:1]
|
||||
# Keep awake only the devices Artemis actually manages: serials claimed in
|
||||
# the device pool by an active execution lock or a live queue reservation.
|
||||
# Other devices sharing the same ADB server belong to unrelated tools or
|
||||
# users, and their power policy must not be touched.
|
||||
try:
|
||||
from artemis.runtime.device_pool import device_pool
|
||||
|
||||
claimed = device_pool.get_claimed_serials()
|
||||
except Exception as exc:
|
||||
logger.debug(f"Could not query claimed devices for the awake policy: {exc}")
|
||||
return []
|
||||
return [serial for serial in serials if serial in claimed]
|
||||
|
||||
|
||||
class ScreenAwakeService:
|
||||
|
||||
@@ -398,6 +398,30 @@ class DevicePool:
|
||||
"""Return ready devices that are not currently holding an execution lock."""
|
||||
return [d for d in self.list_devices() if d.state == "device" and not d.is_busy]
|
||||
|
||||
def get_claimed_serials(self) -> set[str]:
|
||||
"""Return device serials Artemis currently claims on the ADB server.
|
||||
|
||||
A device is claimed while any Artemis process holds its execution lock
|
||||
or has a live pending queue reservation targeting it. Placeholder
|
||||
reservations not yet bound to a concrete device ("pending"/"any")
|
||||
claim nothing. Read-only: computed purely from cross-process lock and
|
||||
queue metadata, without any adb traffic.
|
||||
"""
|
||||
claimed: set[str] = set()
|
||||
try:
|
||||
for owner in DeviceExecutionLock.get_active_owners().values():
|
||||
if owner.device_id:
|
||||
claimed.add(str(owner.device_id))
|
||||
for item in DeviceExecutionLock.get_queued_tasks():
|
||||
serial = item.get("device_serial")
|
||||
if serial:
|
||||
claimed.add(str(serial))
|
||||
except Exception as exc:
|
||||
logger.debug(f"Could not compute claimed device serials: {exc}")
|
||||
claimed.discard("pending")
|
||||
claimed.discard("any")
|
||||
return claimed
|
||||
|
||||
def select_device(self, preferred_serial: str | None = None) -> str | None:
|
||||
"""Select a target device serial for task execution.
|
||||
|
||||
@@ -419,16 +443,6 @@ class DevicePool:
|
||||
# If not detected by ADB, still return it so ADB can attempt connection
|
||||
return preferred_serial
|
||||
|
||||
# Prefer active ready device from readiness engine if available
|
||||
try:
|
||||
from artemis.core.diagnostics import readiness_engine
|
||||
|
||||
active_serial = readiness_engine.get_active_device_serial()
|
||||
if active_serial and any(d.serial == active_serial and d.state == "device" for d in all_devs):
|
||||
return active_serial
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Pick first idle device
|
||||
for dev in ready_devs:
|
||||
if not dev.is_busy:
|
||||
|
||||
Reference in new issue
Block a user