Skip to content
Open
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
23 changes: 18 additions & 5 deletions src/ragger/backend/speculos.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,18 +179,31 @@ def __enter__(self) -> "SpeculosBackend":
self.logger.info(f"Starting {self.__class__.__name__} stream")
self._client.__enter__()

# Wait until some text is displayed on the screen.
# Wait until the app has rendered its first screen.
#
# Primary check: OCR-based text events (works when speculos can
# identify characters from the rendered bitmaps).
#
# Fallback check: screenshot comparison. Some SDK versions (e.g.
# API_LEVEL >= 26) copy font bitmaps to a RAM buffer before drawing,
# which breaks the speculos launcher's pointer-based character lookup.
# In that case no text events are produced, but the screenshot is
# still correctly rendered. Comparing consecutive screenshots lets
# us detect that the app has started without relying on OCR.
start = time()
while not self._retrieve_client_screen_content()["events"]:
# Send a ticker event and let the app process it
initial_screenshot = self._client.get_screenshot()
while True:
if self._retrieve_client_screen_content()["events"]:
break
screenshot = self._client.get_screenshot()
if screenshot != initial_screenshot:
break
sleep(0.1)
if (time() - start > 20.0):
raise TimeoutError(
"Timeout waiting for screen content upon Ragger Speculos Instance start")

self._last_screenshot = BytesIO(self._client.get_screenshot())

# Save current screenshot as _home_screenshot.
self._home_screenshot = self._last_screenshot

return self
Expand Down
Loading