* docs: research and plan for EA and Ubisoft stores
* feat(ea): EA store with sign-in, library, native downloads, updates and launch without the EA app
* perf(ea): fetch large archive records as parallel ranges
* fix(ea): register game display names
* fix(ea): license legacy EA Core games and harden the LSX endpoint
* fix(ea): run legacy Origin SDK games with a stand-in Origin process
* fix(ea): trust only the prepared game on LSX and stop stale library syncs
* fix(ea): close LSX sessions on stop and drop clients that never hand-shake
* fix(ea): require every hashed field before licensing or caching a probe
* fix(ea): trust one LSX session per launch
* fix(ea): serialize the library cache write with sign-out and rerun a skipped sync
* fix(ea): hand off library sync requests under one lock
* fix(ea): clear the sign-in before invalidating the library
* fix(ea): serialize sign-out with token refresh and with the library cache
* fix(ea): LSX trusts only verified peers, new launch closes old sessions, exit stops its own game
* fix(ea): LSX hides profile and presence from unverified peers
* fix(ea): LSX handshake has a fixed deadline and untrusted sessions yield their slot
* fix(ea): LSX never registers a client after its listener was stopped
* fix(ea): LSX evicts each untrusted session at most once
* fix(ea): LSX admission and eviction share one lock and keep the cap
* fix(ea): LSX trust promotion excludes eviction
* fix(ea): LSX launch generation guards restarts and drops results after shutdown
* fix(ea): LSX publishes launch state under the admission lock and tags accepts by generation
* fix(ea): LSX restarts rebind its listener and promotion checks the launch generation
* fix(ea): record why EA refuses a game licence in the store log
* chore(ea): log owned offers and the full licence refusal
* chore(ea): log the account's entitlements when no game licence is granted
* chore(ea): log legacy entitlements when no game licence is granted
* chore(ea): log only the refused game's own entitlements
* fix(ea): skip trial launchers flagged 1 and license games whose LSX peer Android cannot name
The session's TU_DEBUG=sysmem is meant for the Steam client and
Chromium-based apps. Flatpak and Snap apps inherited it, so emulators
and other programs installed that way rendered through system memory.
droiddeck-game-env now holds the Chromium check next to game_gpu, and a
small droiddeck-game-gpu wrapper applies both to any program. The
AppImage, Flatpak and Snap launchers use it, so the rule lives in one
place.
The session sets TU_DEBUG=sysmem for the Steam client's interface and hands
games their own value in DROIDDECK_GAME_TU_DEBUG, which droiddeck-game-env
applies to Steam launches (#1188). droiddeck-appimage-run never did, so
emulators and other AppImage programs rendered every pass through system
memory instead of Turnip's per render pass choice.
Apply the game value in droiddeck-appimage-run the same way: an empty
value unsets TU_DEBUG, any other value replaces it. Chromium-based apps,
like the Steam client's own interface, keep the session's setting.
Mesa 26.0.8, which the Ubuntu runtime builds, carries the backport of
"zink: create views for samplers lazily", which dropped the depth/stencil
aspect check in init_sampler_view(). On drivers with
needs_zs_shader_swizzle (Imagination) every colour view with a constant-1
alpha, such as RGBX/BGRX textures, then got the red-only depth swizzle
view, so Steam's interface and games showed red as R=G=B.
Carry Icenowy Zheng's upstream fix d55418dae7 (Mesa MR 41923), which
restores the aspect check. It applies on top of patch 0004.
* docs: DroidDeck 0.7.0 release notes
* docs: add 0.7.0 release note media
* docs: drop the 30 second summary from the 0.7.0 notes
* docs: add the dual-screen Dashboard shots to the 0.7.0 notes
* docs: show the Dashboard as one stacked dual-screen image
* docs: add the swap screens GIF to the 0.7.0 notes
* docs: swap in the new Syncthing screenshot
* docs: add the HUD dock GIF to the 0.7.0 notes
* docs: add the Game Jolt screenshot to the 0.7.0 notes
* docs: show the full screen in the HUD dock GIF
* docs: merge the GPU bullets, add the no proprietary components line, put images above their bullets
* docs: add the 0.7.0 APK download button to the release notes
* docs: add the first-time contributors to the 0.7.0 notes
* docs: add KeegantheVeganat0r as a first-time contributor
* docs: add the shared Steam libraries screenshot to the 0.7.0 notes
* docs: rewrite the shared Steam libraries bullet and move it up
* docs: add the Mali support photo to the 0.7.0 notes
* docs: center 0.7.0 release media
* docs: credit The412Banner for Mali support in 0.7.0 notes
* docs: add the KDE desktop GIF to the 0.7.0 notes
* docs: add the desktop and swapped game clips to the 0.7.0 notes
* docs: use the Duo photo for the swapped screens
* docs: replace the swap screens GIF with the Duo recording
* docs: drop the swap screens GIF
* docs: keep a blank line before each release image
* docs: tweak 0.7.0 release notes
* docs: move smaller 0.7.0 items to improvements
* docs: fold the bottom-screen HUD into the Strip HUD bullet
* docs: pair the swap screens and KDE desktop media
* docs: move Game Jolt and Syncthing up in 0.7.0 features
* docs: put the swap screens and KDE desktop cluster after Mali in 0.7.0 features
* docs: reword shared Steam libraries and reorder KDE desktop bullet
* docs: add recent merged PRs to the 0.7.0 notes
* docs: auto component updates follow DroidDeck-Proton only
* docs: add input profiles, low-RAM memory, driver Auto and other recent changes to the 0.7.0 notes
* docs: add the second-screen layout editor to the 0.7.0 controller profiles notes
* docs: refresh the 0.7.0 pull request and contributor counts, mention controller profiles in the summary
* docs: 0.7.0 notes add the latest fixes and the DroidDeck-Proton, DD-Turnip and component changes
Adds the user-visible pull requests merged after the last refresh (Library
sort, runtime pack update, desktop app launches, GitHub AppImage variant,
DroidDeck-Proton default, component auto-update cleanup, UBWC and FEX preset
settings, controller navigation) and a section for what shipped in
DroidDeck-Proton 11-11.10 to 11-12.3, DD-Turnip 0.4.0 and DroidDeck-Components
since 0.6.9.
---------
Co-authored-by: maxjivi05 <maxjividen@gmail.com>
World of Warcraft, Classic and Forever get an Addons tab in the Library. It imports addon zips into the right Interface/AddOns folder, lists the installed addons, and deletes one after a confirmation.
* chore(i18n): translate every missing string in all locales
Adds the 87 strings the bottom-screen Dashboard and in-game stats pages
introduced to all 32 locales, plus the 51 older settings strings Japanese
and the 50 Chinese locales were still missing. Every locale now has all
3456 translatable strings with the same placeholders as English.
Also translates 36 entries that were still English where the language
does not use the English word, and makes es-419 touch_app_id use the same
%1$s placeholder as English.
* chore(patches): drop comments from the lines downstream patches add
Removes comment lines and trailing comments from lines our patches add,
with hunk headers recounted. Lines that a later patch uses as context
and the upstream backport 0123 are left as they are.
The gamescope, FEX, proot and xodus series still apply to their pinned
sources, and the patched trees differ only in those comments.
test_hud_frames now finds the HUD writer by its first declaration.
* docs: credit Greenlight, Better xCloud, viture-v2, GameNative and DiRTTelemetryErrorFix
These were credited only in source headers and NOTICE files.
* chore: remove source comments and unused functions
Removes explanatory comments from first-party Kotlin, Java, C, C++,
Rust, TypeScript, Python, shell, Gradle, CMake and workflow files.
License and attribution headers stay, and vendored third-party trees,
generated files and license files are untouched. A shellcheck directive
is kept, and udevmon's fallthrough comments became fallthrough attributes.
Syntax trees and token streams match the previous sources apart from the
comments and Python docstrings. Module docstrings that argparse prints
are kept, and device-smoke.sh prints the same --help text from a heredoc.
Also removes 37 functions and 4 fields that nothing referenced.
* chore: remove comments from the Syncthing integration and the latest main sources
* docs: credit Syncthing and the syncthing-android fork
* chore(i18n): translate the Syncthing strings in all locales
The 107 strings the Syncthing integration added are now in all 32 locales.
sync_web_path_locked names the Syncthing tab by its label.
* docs: credit @xXJSONDeruloXx for the HUD metric readers
The CPU, GPU load, thermal and battery readers come from their
PerformanceHudView pull requests #777, #877, #991, #1406 and #1573.
The FusionHUD credit line is unchanged.
* docs: credit the HUD metric readers to @xXJSONDeruloXx's work
* fix: AYN Odin handhelds are single-screen in automatic dual-screen mode
* Use a second screen only when more than one physical screen is lit, instead of excluding AYN models
* fix: open the session panel when the second screen turns on, and keep the On mode's display choice
* fix: let the session panel open again after its screen goes away and returns
* fix: Automatic dual screen needs a touchscreen for the second panel instead of counting lit displays
* fix: check the second screen again when a touchscreen comes back after the display
* fix: check the second screen again when a touchscreen is added or removed, and on resume
* Keep the second screen panel closed once the session has ended
The session HUD is FusionHUD (Bannerlator's HUD) with every reading taken from
the same source, and worked out the same way, as the MangoHud build that runs
Steam's performance overlay in a DroidDeck session.
- gamescope patch 0125 (gamescope-3.16.29-p19) shares the frame times that
mangoapp reads (one per signalled commit of connector 0) in a ring named by
DROIDDECK_HUD_FRAMES; the app reads it once per display frame and counts the
compositor's frames when gamescope sends none.
- MangoHud's rules: FPS over periods of at least 500 ms, frame time = 1000/FPS,
200-frame graph on a fixed 0-50 ms scale; CPU, GPU, temperatures, RAM, swap,
VRAM and battery from MangoHud's sources. Zones 22/26/28 are typed as GPU and
DDR sensors, so Steam's overlay CPU temperature no longer includes them.
- Five sizes in a panel shaped like the DroidDeck mark, with a centred header,
one left edge, neon outline and FPS; Minimal is the default size. Settings on
a new "Performance HUD" drawer page, with Bannerlator's options.
- The HUD reads sensors and polls frames only while it is drawn (not while
hidden, in picture-in-picture or behind another app), keeps its place after
picture-in-picture, and the diagnostics export has its own reader.
Device-tested on the AYANEO Pocket FIT: same readings as Steam's overlay side
by side in Dead Cells; the HUD updates in a game, hides in picture-in-picture
and comes back in place, no crashes.
Steam's arm64 streaming_client only decodes through a V4L2 stateful
decoder and libdrm dumb buffers, neither of which exist on Android, so
streams from a PC never showed a picture. The preload now offers it a
/dev/video-dec0 and a libdrm stand-in backed by dma-heap buffers, and
each frame is decoded by the app's MediaCodec (Qualcomm low-latency
mode) over the encoder socket, falling back to the FFmpeg in Steam's
runtime.
skate. under ReSkate crashed with an access violation in Skate.exe 12 to
60 seconds after it started at the default feature level 12_2; at 12_1
it loads San Vansterdam and plays. The rule matches Skate.exe with
ReSkate.dll beside it, so it covers ReSkate started from skate.'s own
Steam entry and as a non-Steam game, and a game profile can still set
another level.
Battle.net games now install like Epic, Xbox and itch games: Install,
pick a location, and the download runs in the Downloads tab while the
Stores page stays open. droiddeck-battlenet starts Blizzard's own Agent
on its own under a headless gamescope and drives its local API, so no
window opens and nothing waits on the Battle.net client.
- Progress, speed and time left come from the Agent, with pause, resume
(the Agent keeps what it downloaded) and cancel, which uninstalls the
partial game and removes its folder.
- A job only finishes once the Agent has really run it and the game is
playable; the first status after a request can still describe the
previous operation.
- Installed games check Blizzard's version service and show Update when
the build on disk is behind; the update repairs missing files too.
- Battle.net games can be uninstalled from their page through the Agent.
- Games land in the chosen location: internal storage, other storage or
a Games folder.
- The hero keeps its action row clear of the playtime column.
GE-based Protons, the default with the x86-64 Steam client, run umu-protonfixes. Its Black Ops III fix switches the prefix to Wine's ALSA driver, which has no device here and replaces DirectAudio, and its Dark Souls Remastered fix runs the VC++ 2017 installer, which fails under ARM64 Proton.
Steam's ARM64 client has no desktop-portal file chooser, so
SteamClient.System.OpenFileDialog failed at once and every Browse button
(Add a Non-Steam Game, shortcut target, library folder) did nothing.
The Steam UI bridge now answers it with a GTK file chooser run under
Steam's reaper, so gamescope shows it over Steam.
Wine asks for userfaultfd with the i386 syscall number on arm64, so it
never gets one and falls back to mprotect and a SIGSEGV per first write,
which under proot is a ptrace stop each time. libblsession hands it the
real userfaultfd and, where Android refuses the PAGEMAP_SCAN ioctl, answers
it from /proc/self/pagemap and UFFDIO_WRITEPROTECT.
PipeWire's access module checks each client's /proc/<pid>/root for a
Flatpak marker. Where that lookup fails under proot (seen on a nubia
NX809J), PipeWire treats the client as sandboxed and holds it until the
session manager grants permissions, and WirePlumber, itself held, never
does. gamescope then waits forever for its capture stream and never
starts Steam: a black screen until the session is closed.
The session's PipeWire now gives both of its sockets unrestricted access
and WirePlumber keeps those clients at full permissions, so nothing
depends on that lookup.
perf: files in an SD card library resolve through the fast path instead of proot
A library bound at several guest names (droiddeck-sd, bannerlator-sd and
case variants) made every symlink and /proc/self/fd readlink under it fall
back to proot. The fast path now orders its binds the way proot does and
gives each host path the name proot would, and lstat("link/.") follows
the link as the kernel does.
Co-authored-by: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com>
A process's status read for another process is served read-only, so
Chromium's ReadOnlyFile check no longer kills the browser. Chromium-based
AppImages without chrome-sandbox get --no-sandbox, and Flathub Chromium and
Electron apps skip zypak's spawn portal, which cannot work here.
Flatpak starts bwrap with an empty environment, so the bwrap shim lost DROIDDECK_BWRAP_SOCKET and dialled the default package's socket. The session now writes the socket name to /etc/droiddeck/bwrap-socket and the shim reads it when the variable is missing.
Fixes#1092
Games launched from Steam get Turnip's own per-render-pass choice between
tile memory and system memory again; TU_DEBUG=sysmem now stays with the
Steam client, whose interface it was set for. A per-game TU_DEBUG, the
debug override file and the Adreno 710/720 driver still win. On the
REDMAGIC tablet (Adreno 840) PEAK runs 46.8 -> 52.3 fps over 7 alternating
pairs and Valheim's 3D menu needs 12.6 % less GPU time per frame; light
games are unchanged.
droiddeck-seed-redists remembers the identity (inode, size, mtime) of each
prefix registry it has verified and skips re-reading it while it is
unchanged. Steam started after it on every session, ~1.8 s later.
SessionFiles keeps a ledger of the files it staged for the installed APK
and copies only the ones that changed, ~180 ms less per session start.
Session start to Steam ready: 5.57 -> 3.57 s.
RPCS3's AppImage could not start: its own runtime unpacks the image with
a dwarfsextract it runs from a memfd, which Android refuses (EACCES), and
it has no other way to run it. Emulator AppImages for arm64 now start
through the shipped uruntime, which falls back to a file in /tmp.
RPCS3 then stopped with "Null object" in utils::shm (errno 13): it reads
/proc/sys/vm/overcommit_memory to pick memfd for guest memory, and apps
cannot read it. The guest now gets the kernel's default policy (0) there
when the real file is unreadable, like file-max.
A GOG download only places the files, so games that look up their own registry keys (Fallout: New Vegas reads HKLM\Software\Bethesda Softworks\FalloutNV "Installed Path") said they were not installed. Every GOG launch now reads the setRegistry actions of the game's goggame-<id>.script and imports them into the prefix's 32-bit view through Proton's reg.exe, once per change of the script, so games already downloaded are fixed on their next launch.
fix: let Wine write hooks into code FEX has translated
Wine 11's wineserver writes another process's memory with process_vm_writev,
which the kernel refuses on a page that is not writable. FEX's WoW64 layer
keeps the pages it has translated read-only to catch self-modifying code and
re-protects them right after a program unprotects them, so WriteProcessMemory
and NtWriteVirtualMemory into ntdll failed with a partial copy and Ubisoft
games stopped at "Error at hooking API NtProtectVirtualMemory". Wine only
falls back to /proc/<pid>/mem on ENOSYS or EPERM.
libblsession now completes a single-buffer write that wineserver was refused
with EFAULT through /proc/<pid>/mem, the way Wine wrote before Wine 11. Other
programs and every other error keep the kernel's answer. The iovecs are read
with process_vm_readv, so a bad pointer still returns EFAULT, and offsets are
64-bit in the i386 build.
* Steam x86-64 client: menus come up, sign-in stays put, games listed once
Switching the Steam client from arm64 to x86-64 left the client on a blank
screen behind "Downloading the Steam client update 100%", and each switch
signed one of the clients out.
- The x86-64 client is Valve's steamrt64 platform, but it was installed and
synced from the ubuntu12 manifest, which lags it (1792108788 against
1792192922). The client was therefore never the arm64 client's build, the
arm64 web helper was never used, and the client then updated itself in
place after the helper had been chosen. Install, sync and the build check
now read the steamrt64 manifest.
- The x86 web helper's GPU process loads libpci, which exits when
/sys/bus/pci/devices lists a device whose files the app may not read (a
RedMagic's PCIe root ports). Every GPU process exited with status 1, even
in software, until Chromium gave up and the menus stayed blank. An empty
folder is bound over /sys/bus/pci/devices on such devices.
- Steam refuses one client's login token from the other ("Invalid
Password" for a token the arm64 client signed in with minutes before), so
copying the newer token at every start signed the other client out. Each
client now keeps its own token; a client with no accounts only gets the
other's account list.
- Games could be listed twice: an added game whose folder a Steam import
already covers is now shown as that Steam game only, a client switch
drops the old client's imported entries, an import stays one when its
ownership cannot be confirmed instead of gaining a shortcut beside it,
and only the client's own library folders count as an install.
* Steam x86-64 client: share the arm64 sign-in again
The x86-64 client refused the arm64 client's login token because it did
not know the account's SteamID: it takes it from Accounts in
config/config.vdf, which this script creates without one. It logged on as
[U:1:0] with a valid token, Steam answered "Invalid Password", and the
client dropped the token and AutoLoginUser, so every switch asked for the
password.
The newer sign-in is copied between the clients again, each start adds
the accounts either client knows to the other's config.vdf, and an
AutoLoginUser or RememberPassword one client lacks is filled in. Device:
the x86 client signs in with the arm64 token on a fresh install and on an
install left signed out, and the arm64 client stays signed in.
- Pace the session at the rate the panel actually runs. When the system
keeps a lower rate than the mode DroidDeck asked for (a vendor game
assistant holding 120 Hz while 185 Hz was requested), gamescope,
Xwayland and the compositor's presentation feedback were told 185 Hz,
and Steam's interface drew every 10.8 ms out of step with the panel.
- Build the DirectAudio PulseAudio sink from source (LGPL-2.1-or-later,
The412Banner/directaudio v1.1.0) with its max request kept to its ring
target. Advertising 100 ms made PulseAudio grow every client's buffer
to about 112 ms, so Steam's interface sounds played that late.
* Add VITURE glasses support: hardware control, 3D, head tracking
Glasses get their own controller over the MCU (permission, 120 Hz default, brightness, volume, sunblock, 2D/3D) and the game moves onto them when plugged in. The IMU drives Cardboard head tracking and the SteamVR driver. 3D falls back to one eye's view on phones that can't send the 3840x1080 signal. Options open from a glasses button in game and on the Steam page.
* Drop the glasses settings like Steam's: Play-style button, Settings lip, tabs
* Hang the glasses Settings lip over the top of the button
* Space glasses MCU commands so the IMU rate sticks, fit fixed resolutions to the glasses
* Keep Steam alive with SteamVR registered, run SteamVR at the glasses' rate, keep the glasses lip on top
* Fit VR games on the glasses: full view, seated origin at the head, pad hands reach with the d-pad
* Let the pad hands reach a metre out so buttons with deep colliders press
* Show every VR frame in order at 120 fps: wait for SteamVR's GPU work, present only finished copies, skip the grace on idle shared counters
* Glasses: SteamVR starts and stops with them, closer view with a field of view setting, Recenter on the pad
* Glasses: SteamVR field of view defaults to 90°
* VR pad hands: sticks move and aim the hands, left stick click switches the sticks to the game, d-pad pulls a held hand
* Glasses: Play SteamVR beside the glasses button instead of starting SteamVR with them, pad hands drawn as Index controllers and off while other VR controllers are connected, glasses sheet tabs sized like Steam's
* Track glasses mode, refresh-aware glasses window, align Play SteamVR with Play Steam
* Fix 3D on the glasses: full-res SteamVR presenter, revert VR 3D at session end, coalesce vsync ticks, no session restart after end
* Address review: glasses output after installs and session end, VR revert retry, display fallback, presenter swapchain retry, agent hex checks, drawer bumpers, glasses translations, docs
* Harden VITURE stereo negotiation and output refresh tracking
* Localize stereo recovery feedback and record Astra reconnect tests
* Improve test failure diagnostics and refresh Astra firmware findings
* Handle VITURE docks separately and reject truncated USB frames
* Glasses: remember a 3D fallback per model, docks as display only, VR timing fixes
- A 3D attempt that ends at the 640x480 fallback is remembered for that glasses
model, so Play SteamVR no longer blacks out the glasses after every restart;
Retry clears it and "3D for VR games" stays reachable
- A VITURE Mobile Dock on its own no longer counts as glasses; through a dock
Play SteamVR is hidden and the sheet shows the output and why there is no control
- HDR is probed on the glasses when the session starts there
- Glasses frames with a mismatched checksum are marked in the status frame log
- SteamVR layer and driver vblank counters stay monotonic across refresh changes;
one-eye render scale applies from activation and on mono/3D switches
- Compositor binds announce the refresh clients were last told; the presenter
retries a failed first swapchain
- Dead strings and helpers removed; docs updated
* Glasses: drop USB frames with a bad checksum
* Glasses: count frames dropped for a bad checksum
* Feat/viture xr (#907)
* Add RayNeo Air and GT support to the XR glasses pipeline
* Add RayNeo Air and GT support to the XR glasses pipeline
* Checkpoint glasses tracking, calibration, and SteamVR launch integration
* Checkpoint glasses tracking, calibration, and SteamVR launch integration
* Add XREAL 1S support and correct GT and Pro 2 tracking
* Add XREAL 1S support and correct GT and Pro 2 tracking
* Fix mirrored glasses tracking and recover SteamVR after device loss
* Fix mirrored glasses tracking and recover SteamVR after device loss
* Document confirmed XREAL 1S brightness control
* Document confirmed XREAL 1S brightness control
* Fix SteamVR glasses defaults and rendering controls
* Fix SteamVR glasses defaults and rendering controls
* chore: keep only the 3 newest session log folders (#852)
* chore: add agent comment rules (#748)
Co-authored-by: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com>
* Fix SteamVR polling, VITURE checksums, and fence tracking
Keep manual SteamVR launches polled, discard corrupt VITURE packets, and retire Vulkan fences out of order without blocking submissions at a fixed capacity. Preserve the contiguous completion watermark used by the presenter.
Fix optional Windows launcher configuration and audited helper staging. Add Android, Windows, and native tracker regression coverage.
* Fix SteamVR polling, VITURE checksums, and fence tracking
Keep manual SteamVR launches polled, discard corrupt VITURE packets, and retire Vulkan fences out of order without blocking submissions at a fixed capacity. Preserve the contiguous completion watermark used by the presenter.
Fix optional Windows launcher configuration and audited helper staging. Add Android, Windows, and native tracker regression coverage.
* fix: wireless ADB page names the child-process switch the way Android shows it (#848)
* l10n: refresh stale and untranslated strings in es, fr, ko, ru (#850)
* l10n: refresh stale and untranslated strings in es, fr, ko, ru
- mode_added_art_hint: now mentions Steam then SteamGridDB (all four locales).
- wincomp_needs_installer / wincomp_installers_note: es and ko still described
the old "coming soon" behaviour; align with the current English text.
- summary_remove_game: was still English in all four locales.
Machine-assisted translation; native-speaker review is welcome.
* l10n(es): say registro, not grabación, for the missing installer record
---------
Co-authored-by: ovurrsl <ovurrsl@users.noreply.github.com>
* fix: a failed cloud save recovery no longer ends the app (#846)
The cloud-recovery thread started at every app start had nothing to
catch an error, so one went to CrashHandler, which halts the process
with status 2. In unit tests the thread can outlive the test that
started it, fail on the torn-down preferences, and take the whole test
run down. The error is now logged and the thread ends.
Co-authored-by: Kirk <12691869+KirkPatrickJunsay@users.noreply.github.com>
* fix: an interrupted Linux runtime download resumes instead of starting again (#847)
* fix: an interrupted Linux runtime download resumes instead of starting again
installOnce() asked the downloader to resume but always deleted the archive in its finally block, so the next attempt began at zero. The archive is now named after the release version and checksum, a failed download keeps what it fetched, and archives of other releases (and the old fixed name) are removed. A checksum or extraction failure still deletes the file.
* test: Downloader resumes a cut-off download from the bytes it kept
Starts a socket server that promises the whole file, hangs up part way and then answers a Range request, and checks that the second downloadFile call resumes with the right offset and ends with identical bytes.
* fix: a resumed download discards a 206 that does not start where the kept bytes end
Downloader appended every 206 response to the partial file without
looking at Content-Range. A server or proxy that answers a Range request
with a different offset would leave a corrupt file. Check that the range
starts at the kept length; otherwise delete the partial file and start
again without a Range header.
Adds a test with a server that answers the Range request from offset 0.
---------
Co-authored-by: ovurrsl <ovurrsl@users.noreply.github.com>
* l10n: German, French, Spanish, Italian, Portuguese and Russian for the zRAM, reset-settings and store free-space strings (#849)
* l10n: German, French, Spanish, Italian, Portuguese and Russian for the zRAM, reset-settings and store free-space strings
Adds the strings values-de, values-it and values-pt were missing (14 each) and the six that values-fr, values-es and values-ru were missing. Machine-assisted drafts that follow each file's existing register and terms; native review is welcome.
* l10n: correct missing active swap translations
---------
Co-authored-by: ovurrsl <ovurrsl@users.noreply.github.com>
Co-authored-by: xXJsonDeruloXx <danielhimebauch@gmail.com>
* 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>
* feat: droiddeckctl reports on-screen pacing (recover #843) (#855)
feat: droiddeckctl pacing reports the frames that reached the screen
Reads SurfaceFlinger's timestats for the game's layer (or the session's
SurfaceView) over a capture: frames on screen, fps on screen, the
present-to-present histogram and how many intervals were off the usual
cadence. Records split by a refresh-rate change are summed. A game's own fps
counter counts frames handed over, so it can't show dropped or doubled frames.
Co-authored-by: angelrenefm <17342133+angelrenefm@users.noreply.github.com>
* fix: Steam can restart more than twice in a session (#754)
* fix: Steam can restart more than twice in a session
Every exit 42 counted toward the cap that stops an update which will
not install, and the count was never cleared, so the third restart of
a session ended it however far apart they were. A client that ran for
a minute before asking is not that loop: the count starts again.
* fix: measure the client's run time as it exits
The time spent collecting logs and checking FEX after the client exits
counted toward its run, so a slow cleanup could make a quick exit 42
look like a long one and clear the count.
---------
Co-authored-by: Kirk <12691869+KirkPatrickJunsay@users.noreply.github.com>
Co-authored-by: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com>
* fix: the front end keeps its page when the Fold is folded or unfolded (#832)
* fix: the front end keeps its page when the Fold is folded or unfolded
MainActivity, FileManagerActivity, FilePickerActivity and StoreLoginActivity did not declare the screen-size configuration changes, so folding or unfolding a foldable recreated them and dropped their in-memory state. They now handle orientation, screenSize, screenLayout, smallestScreenSize and density themselves, like SessionActivity already does. uiMode is left out on purpose.
* fix: store login keeps rebuilding its toolbar when the display density changes
StoreLoginActivity builds its toolbar in code with dp-to-pixel values taken at creation time and has no onConfigurationChanged. It no longer declares density in configChanges, so a density change recreates it as before this PR. Size and layout changes are still handled in place.
---------
Co-authored-by: ovurrsl <ovurrsl@users.noreply.github.com>
* Release pointer buttons without replaying stale motion (#803)
* Fix cursor warping on native touch down
* Preserve input cleanup without replaying stale pointer motion
---------
Co-authored-by: siyuan.qsy <siyuan.qsy@alibaba-inc.com>
* l10n: translate the strings added since #284 into zh-CN, zh-HK, zh-TW and ja (#539)
* l10n: translate the 184 strings added since #284 (zh-CN/HK/TW, ja)
The stores, cloud saves, Windows components, Steam touch, desktop
removal and background-downloads strings landed after #284's
translation snapshot, so every one of them fell back to English.
Translate all 184 into Simplified Chinese, Traditional Chinese
(Taiwan and Hong Kong) and Japanese, keeping each locale file's own
vocabulary (工作階段/會話, 解除安裝/卸載, 元件/組件, 設定).
Also fix four Hong Kong strings that kept the simplified 着色器.
* l10n(zh): fix stale and ambiguous strings found in review
Severe: summary_remove_game was untranslated English in all three
files; mode_added_art_hint, wincomp_installers_note and
wincomp_needs_installer still described the pre-#480/#492 English.
Also: distinguish the Setup wizard from Android system settings in
zh-HK/zh-TW (初始設定 / 系統設定 / Android 設定), unify library as
收藏庫, component as 組件 in zh-HK, session as 會話 in zh-HK, account
as 帳戶 in zh-HK, Trending as 趋势/趨勢, Forget as 清除, reword the
re-applied-at-launch, action-failed and already-in-Games strings, and
play as 執行/開啟遊戲 in zh-TW/zh-HK.
* l10n(ja): fix stale and ambiguous strings found in review
---------
Co-authored-by: Dantalian <Dantalian-dev@users.noreply.github.com>
Co-authored-by: xXJsonDeruloXx <danielhimebauch@gmail.com>
* Rebuild and verify Windows VR runtime components
* Rebuild and verify Windows VR runtime components
* Add top, bottom, and centered picture positions for Steam sessions (#871)
* fix: dependency scan ignores folders above the game folder (#859)
* DroidDeck-Proton: get releases from the Droid-Deck org repo
DroidDeck-Proton is now built and released on Droid-Deck/DroidDeck-Proton
(11-9.1 is Latest there), so the Components page, the update check and the
guest installer read releases from the org repo instead of The412Banner's.
* feat: low-latency controller and touch toggles in the session drawer (#808)
* fix: SteamGridDB lookups no longer stick as "no match" after a failure; add a search to the art chooser (#876)
* feat: Steam home wall fills from the signed-in library instead of store picks (#878)
* test: cover GPU family and support classification (#880)
* Fix local builds on Linux failing after the first Comet build (#866)
* feat: sort the store library and installed tabs, and switch between card and list views (#798)
* feat: three-finger tap toggles Steam's on-screen keyboard in game mode (#782)
* fix: keep Quest-patched Turnip as the auto default (#853)
* Fix deploy_local.sh and droiddeckctl not finding a phone connected over wireless debugging (#864)
* fix: keep proot sessions alive when the kernel loses fork events (#457)
* fix(quest): correct desktop and Steam display corruption across sessions (#733)
fix(quest): stabilize desktop and Steam layer presentation
Keep Quest SDR scenes and the black backdrop off the Android Vulkan swapchain regardless of session order or HDR preferences. Only report the first frame after client content is submitted.
Add backdrop lifecycle and first-frame regression coverage. Record the user's successful Quest 3 Test 2 result.
Co-authored-by: xXJsonDeruloXx <danielhimebauch@gmail.com>
* fix: keep SteamVR syscall hooks and report Steam crashes (#905)
* fix: preserve SteamVR syscall hooks
* fix: report Steam crashes through gamescope
* fix: honor glasses pacing and resolution in SteamVR launches
---------
Co-authored-by: connor g <connorsspam1992@gmail.com>
Co-authored-by: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com>
Co-authored-by: Yassine Gherbi <y.gherbi.dev@gmail.com>
Co-authored-by: Resul Övür <92828257+ovurrsl@users.noreply.github.com>
Co-authored-by: ovurrsl <ovurrsl@users.noreply.github.com>
Co-authored-by: Kirk <kirtoy.junsay@gmail.com>
Co-authored-by: Kirk <12691869+KirkPatrickJunsay@users.noreply.github.com>
Co-authored-by: xXJsonDeruloXx <danielhimebauch@gmail.com>
Co-authored-by: angelrenefm <17342133+angelrenefm@users.noreply.github.com>
Co-authored-by: asdf17128 <asdf17128@gmail.com>
Co-authored-by: siyuan.qsy <siyuan.qsy@alibaba-inc.com>
Co-authored-by: Dantalian <wsu091227@qq.com>
Co-authored-by: Dantalian <Dantalian-dev@users.noreply.github.com>
Co-authored-by: The412Banner <the412banner@users.noreply.github.com>
Co-authored-by: The412Banner <205237651+The412Banner@users.noreply.github.com>
Co-authored-by: FX1922 <120828496+FX192@users.noreply.github.com>
Co-authored-by: Muaz Kadan <32595066+muazkadan@users.noreply.github.com>
Co-authored-by: kingokksa <47888451+kingokksa@users.noreply.github.com>
Co-authored-by: Jamie Schenker <jam1esch3nk3r@gmail.com>
Co-authored-by: Jagger15 <jagger2333@live.com>
* Glasses: keep a pending 2D restore and the SteamVR recovery offer, show Play SteamVR only with a picture
* Translate the glasses calibration, XREAL and SteamVR recovery strings
* SteamVR recovery: give a finished teardown time to collect logs before restarting
* Credit the projects the XR glasses support builds on
* Joy-Cons: SteamVR hands from their gyro while SteamVR runs, one combined pad otherwise
* Add experimental Luma tracking and stabilize SteamVR launches
Add native Luma Ultra spatial tracking, optical controllers, and stereo
calibration with DroidDeck styling, imperial/metric measurements, and
pending recenter recovery. Include the pinned hand model and calibration board.
Keep live guest and SDK files outside Android's evictable cache. Filter the
Adreno 840 sysmem override in the shared SteamVR helper, serialize timeline
mirroring, retain invalid optical controllers without event floods, and
prevent an unprivileged scheduling fallback from lowering compositor RTTIME.
Validation: latest APK build and runtime freshness checks pass; 247 affected
glasses/calibration tests pass. Native VR, helper, and packaging regressions
pass. Two earlier phone library launches sustained 60 fps for 308 and 188
seconds without recovery or restart. The newer calibration APK is installed
and checksum-verified; calibrated-hand and sustained gameplay acceptance
remain pending. One existing Android test requires Windows symlink privileges.
* Headsets: settings badge on Play SteamVR instead of a top-right button, both shown only once connected
* Hand tracking: camera-tracked Joy-Cons and bare hands in SteamVR, drawn as white gloves
- Joy-Con movement from the accelerometer (report reordering, per-Joy-Con calibration, zero-velocity updates)
- MediaPipe pose and hand landmarks from the device camera, placement check, per-hand Kalman filter with the Joy-Con
- No controller connected: bare camera hands with Quest-style gestures, 1€ filtered, rendered as a white glove model built from a distance field
- SteamVR safe mode cleared before each start so one crash no longer blocks the driver
* Improve Luma Ultra tracking and isolate device-specific controls
Refine stereo hand and Joy-Con tracking, gesture release, calibration,
recovery UI, diagnostics, display modes, and compositor handling.
Keep Ultra controls and input routing behind a live SDK-confirmed Carina
connection; clear retained spatial mode when other glasses connect.
Add optional UVC transport with pinned dependencies and packaged notices.
Validation: 456 Android tests, ARM64 VR build and native regressions,
47 tooling tests, SDK/UVC-enabled and disabled builds, and 150 packaged
runtime checksums. Two shader compilation tests skipped because the
compiler is unavailable. Hardware interaction gates remain experimental.
* Delay Luma Ultra 6DoF until SteamVR settles
Suspend spatial SDK startup while SteamVR launches, then restore it two seconds
after RUNNING is confirmed. Preserve saved tracking preferences and automatically
recenter same-device restoration, including cancellation and early stop.
Discard superseded launch requests and status replies after session teardown.
Validation: 128 focused JVM tests passed on the isolated commit snapshot; 129
passed with the current local hand-tracking work. Debug build and runtime checks
passed, and the reviewed APK was installed and hash-verified on the phone.
* Clarify glasses and phone camera tracking options
Separate Luma Ultra camera controls from phone-camera tracking so the two
hand-tracking switches have clear sources. Label bare-hand controllers and
Joy-Con position tracking explicitly, explain physical Joy-Con inputs and
camera priority, and update the camera prompt and calibration guidance.
Use fresh phone section and toggle labels so existing translations do not
hide the distinction. Preserve tracking behavior and saved preferences.
Validation: 39 existing UI tests, debug build, and packaged runtime verification
passed. Reviewed changes and installed the APK on the connected phone.
* Fix tracking handoff and shared runtime regressions
Release spatial ownership and controller overrides when output returns to the phone. Preserve USB-loss recovery, keep Vulkan submissions asynchronous, clean persistent guest scratch on runtime removal, and clarify the 6DoF head-tracking control.
* Apply smart-glasses virtual screens across DroidDeck menus
* Finalize Luma hand baseline and document smart-glasses support
Keep raw grayscale-to-RGB Full hand inference, wrist-only Joy-Con reconstruction, bounded visual holds, and the dead-zone rollback. Retain opt-in steady aim, recenter controls, reproducible Lite models, and the JPEG-padding fix.
Remove unsuccessful benchmark-only and USB transport experiments. Document the cross-brand 3DoF matrix, Luma Ultra 6DoF, SDK requirements, and app-wide screen behavior.
* Fix executable permission for SteamVR launcher
* Address hand tracking and VR review findings
* Bound stereo recovery test image comparison memory
* Localize smart-glasses setup and tracking diagnostics
Move calibration controls, status messages, validation errors, distance labels,
and printed-board instructions into Android string resources. Add and update
machine-assisted translations in all 32 supported non-English locale catalogs,
with corrections for recentering, hand tracking, product names, and measurements.
Keep print instructions within the page using text layout that supports wrapping
and right-to-left text. Correct the Lite model toggle description to reflect its
Lite palm detector and Lite landmark model.
Add locale coverage, format-argument, line-break, and measurement checks, plus
French and Arabic calibration UI tests. Preserve tracking calculations and the
shared runtime storage behavior.
Validation: Android resource and Kotlin compilation; 3 localization checks;
68 focused tests; 1,597 JVM tests at a 512 MB heap; French and Arabic UI renders.
* Correct smart-glasses translations from PR review
Fix the 42 localization findings covering hand and head terminology, disabled states, calibration dimensions, camera visibility, capture rejection, and menu references. Correct the repeated capture-error ambiguity in related locales and clarify its English source. Keep Romanian setup instructions consistent with the existing informal voice.
Extend localization measurement validation to distance hints and retry guidance. Verify the recovery screen's palette-dependent text color with one row-sized pixel buffer and guaranteed bitmap cleanup.
Validation: Android resource and Kotlin compilation; 3 localization checks across all supported locales; 68 focused JVM tests at a 512 MB heap.
* Work around SteamVR device loss with Adreno 840 Turnip v0.2.0
* Withdraw ineffective SteamVR flushall workaround
---------
Co-authored-by: maxjivi05 <maxjividen@gmail.com>
Co-authored-by: MaxsTechReview <6025299+maxjivi05@users.noreply.github.com>
Co-authored-by: connor g <connorsspam1992@gmail.com>
Co-authored-by: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com>
Co-authored-by: Yassine Gherbi <y.gherbi.dev@gmail.com>
Co-authored-by: Resul Övür <92828257+ovurrsl@users.noreply.github.com>
Co-authored-by: ovurrsl <ovurrsl@users.noreply.github.com>
Co-authored-by: Kirk <kirtoy.junsay@gmail.com>
Co-authored-by: Kirk <12691869+KirkPatrickJunsay@users.noreply.github.com>
Co-authored-by: xXJsonDeruloXx <danielhimebauch@gmail.com>
Co-authored-by: angelrenefm <17342133+angelrenefm@users.noreply.github.com>
Co-authored-by: asdf17128 <asdf17128@gmail.com>
Co-authored-by: siyuan.qsy <siyuan.qsy@alibaba-inc.com>
Co-authored-by: Dantalian <wsu091227@qq.com>
Co-authored-by: Dantalian <Dantalian-dev@users.noreply.github.com>
Co-authored-by: The412Banner <the412banner@users.noreply.github.com>
Co-authored-by: The412Banner <205237651+The412Banner@users.noreply.github.com>
Co-authored-by: FX1922 <120828496+FX192@users.noreply.github.com>
Co-authored-by: Muaz Kadan <32595066+muazkadan@users.noreply.github.com>
Co-authored-by: kingokksa <47888451+kingokksa@users.noreply.github.com>
Co-authored-by: Jamie Schenker <jam1esch3nk3r@gmail.com>
Co-authored-by: Jagger15 <jagger2333@live.com>
* feat: Epic Games Launcher for Linux
Install Epic's official Linux launcher (EGLv2) from Epic's CDN with Valve's
Steam Runtime 4 and run it under FEX, signed in with the linked Epic account.
Epic games launch through a hidden launcher instance so they get the
launcher's own arguments, with the exchange-code launch as the fallback, and
DroidDeck installs show up in the launcher as installed.
In the launcher, touch scrolls like a phone app and the gamepad drives the UI:
D-pad and left stick move the selection, A opens, B goes back, the right stick
and triggers scroll proportionally, X opens the options menu, Y the keyboard
and LB/RB switch tabs.
* feat: Epic Games Launcher for Linux
Install Epic's official Linux launcher (EGLv2) from Epic's CDN with Valve's
Steam Runtime 4 and run it under FEX, signed in with the linked Epic account.
Epic games launch through a hidden launcher instance so they get the
launcher's own arguments, with the exchange-code launch as the fallback, and
DroidDeck installs show up in the launcher as installed.
In the launcher, touch scrolls like a phone app and the gamepad drives the UI:
D-pad and left stick move the selection, A opens, B goes back, the right stick
and triggers scroll proportionally, X opens the options menu, Y the keyboard
and LB/RB switch tabs.
* Route Epic games through Steam, import launcher installs, offer the second library
- Every Epic launch goes Steam -> Epic Games Launcher -> game; Play inside the open launcher hands the game to Steam
- Games installed from inside the launcher get a Games-tab entry and launch through Steam; the launcher installs to the last Stores target
- Stores install picker offers the Steam second library, with side-by-side choices
- uruntime xattr-only failures no longer fail the launcher unpack (app-extract)
* Hand launcher Play and Steam links to Steam, wait for FEX on first run
Play on a game the launcher just installed is matched to its install
record and handed to Steam. Steam games listed in the launcher open
steam://rungameid links, which now start the game in a Steam session.
Opening the launcher before Steam has downloaded FEX asks Steam for it
and starts Steam instead of failing with no-fex.
* Address review: FEX check, play-in-Steam action, touch route thread, scroll scale
fexReady needs a FEX binary in Steam's FEX tool, not just its folder.
The play-in-Steam action stays until the link is handled, so Run Steam
at startup can't start a session first. The pad touch route reads the
mouse mode without side effects off the main thread and posts the pad
update there. Vertical scroll uses the output height. A status-2 unpack
counts only when AppRun is there. The xdg-open command is tested
end to end for Steam links.
* Open the launcher through Steam, recover dropped shortcuts, sign out of both
The Epic Games Launcher now runs as its own Steam shortcut, so opening
it starts Steam, which opens the launcher, and Play inside it goes to
the running Steam.
Steam dropped a running shortcut from its library when the game exited
after a sleep/wake replay or a server re-logon, and launching it then
waited forever at ShowInterstitials. login1 only replays sleep/wake
when Steam is asleep. The session restarts Steam when a requested
shortcut is missing, and when a game exits with its shortcut gone and
nothing else runs.
Resuming after a long pause no longer reports failure while traced
processes are still waking, so "Steam is paused" goes away on the first
tap.
Signing out of the launcher signs DroidDeck's Epic store out, and
signing out in DroidDeck restarts the launcher signed out and clears
the Epic web cookies.
* Address review: one session-switch poll, Epic setup can't block a session
A new switch confirmation replaces the pending poll instead of adding a
second one that could start the session again. Epic library sync and
install-folder setup at session start are each guarded, so a bad
preference no longer stops the guest from launching.
* Uninstall the Epic Games Launcher from the Games tab
An Uninstall button next to Launch asks first, closes a running
session, and removes the launcher and its runtime. The launcher's
sign-in and install records stay, so its games keep their Games-tab
entries and a reinstall comes back signed in. Its Steam shortcut goes
away on the next Steam start.
* Address review: uninstall only after the session has ended
The launcher's files are removed only once the session is not running
and its phase has ended; a shutdown still in progress after the wait
reports failure instead. The confirmation reads the session state from
the front-end state.
* Find FEX that Steam installed on the second library
Steam's tools on a second library live in DroidDeck's private copy,
which the session binds over the library. The launcher's FEX check
only looked on the shared storage, so with FEX there it always asked
Steam for FEX and only Steam opened. It now checks the private copy
too.
* Start games without Steam, per-game Settings menu with Wine sync
"Start without Steam" now really leaves the Steam client out: the game
runs in its own Proton/FEX through droiddeck-proton-run in a run
session, and the Epic Games Launcher opens on its own with its games
playing in it. Run sessions for these games are not pinned to the big
cores and get DirectAudio and the added-games list like Steam.
The Games tab card is now "Settings", titled "<game> Settings": Start
without Steam, FEX preset, Wine sync (ntsync, fsync, esync, wineserver
or the app default) and Default, which puts everything changed for the
game back to the app's settings. The app-wide Wine sync choice is shown
in the Steam settings Session tab.
* Address review: uninstall guard, routed games, shortcut matching
Opening or reinstalling the Epic Games Launcher waits while it is being
uninstalled. Added games that are Steam installs keep their Start
without Steam setting under their Steam app id and start as that Steam
game. Live shortcut lookups wait for Steam's library to load and match
a same-name shortcut by its executable, so no duplicate is added. The
session treats the open launcher as itself even when it could not tell
its Steam app id.
* Address review: drop a queued launcher switch when it is uninstalled
A confirmed switch to the Epic Games Launcher that is still waiting for
the old session to end is cancelled when the launcher is uninstalled,
and never starts while the uninstall runs. The launcher id test sets
its environment for its own runs only.
* Add VITURE glasses support: hardware control, 3D, head tracking
Glasses get their own controller over the MCU (permission, 120 Hz default, brightness, volume, sunblock, 2D/3D) and the game moves onto them when plugged in. The IMU drives Cardboard head tracking and the SteamVR driver. 3D falls back to one eye's view on phones that can't send the 3840x1080 signal. Options open from a glasses button in game and on the Steam page.
* Drop the glasses settings like Steam's: Play-style button, Settings lip, tabs
* Hang the glasses Settings lip over the top of the button
* Space glasses MCU commands so the IMU rate sticks, fit fixed resolutions to the glasses
* Keep Steam alive with SteamVR registered, run SteamVR at the glasses' rate, keep the glasses lip on top
* Fit VR games on the glasses: full view, seated origin at the head, pad hands reach with the d-pad
* Let the pad hands reach a metre out so buttons with deep colliders press
* Show every VR frame in order at 120 fps: wait for SteamVR's GPU work, present only finished copies, skip the grace on idle shared counters
* Glasses: SteamVR starts and stops with them, closer view with a field of view setting, Recenter on the pad
* Glasses: SteamVR field of view defaults to 90°
* VR pad hands: sticks move and aim the hands, left stick click switches the sticks to the game, d-pad pulls a held hand
* Glasses: Play SteamVR beside the glasses button instead of starting SteamVR with them, pad hands drawn as Index controllers and off while other VR controllers are connected, glasses sheet tabs sized like Steam's
* Track glasses mode, refresh-aware glasses window, align Play SteamVR with Play Steam
* Fix 3D on the glasses: full-res SteamVR presenter, revert VR 3D at session end, coalesce vsync ticks, no session restart after end
* Address review: glasses output after installs and session end, VR revert retry, display fallback, presenter swapchain retry, agent hex checks, drawer bumpers, glasses translations, docs
* Harden VITURE stereo negotiation and output refresh tracking
* Localize stereo recovery feedback and record Astra reconnect tests
* Improve test failure diagnostics and refresh Astra firmware findings
* Handle VITURE docks separately and reject truncated USB frames
* Glasses: remember a 3D fallback per model, docks as display only, VR timing fixes
- A 3D attempt that ends at the 640x480 fallback is remembered for that glasses
model, so Play SteamVR no longer blacks out the glasses after every restart;
Retry clears it and "3D for VR games" stays reachable
- A VITURE Mobile Dock on its own no longer counts as glasses; through a dock
Play SteamVR is hidden and the sheet shows the output and why there is no control
- HDR is probed on the glasses when the session starts there
- Glasses frames with a mismatched checksum are marked in the status frame log
- SteamVR layer and driver vblank counters stay monotonic across refresh changes;
one-eye render scale applies from activation and on mono/3D switches
- Compositor binds announce the refresh clients were last told; the presenter
retries a failed first swapchain
- Dead strings and helpers removed; docs updated
* Glasses: drop USB frames with a bad checksum
* Glasses: count frames dropped for a bad checksum
* Feat/viture xr (#907)
* Add RayNeo Air and GT support to the XR glasses pipeline
* Add RayNeo Air and GT support to the XR glasses pipeline
* Checkpoint glasses tracking, calibration, and SteamVR launch integration
* Checkpoint glasses tracking, calibration, and SteamVR launch integration
* Add XREAL 1S support and correct GT and Pro 2 tracking
* Add XREAL 1S support and correct GT and Pro 2 tracking
* Fix mirrored glasses tracking and recover SteamVR after device loss
* Fix mirrored glasses tracking and recover SteamVR after device loss
* Document confirmed XREAL 1S brightness control
* Document confirmed XREAL 1S brightness control
* Fix SteamVR glasses defaults and rendering controls
* Fix SteamVR glasses defaults and rendering controls
* chore: keep only the 3 newest session log folders (#852)
* chore: add agent comment rules (#748)
Co-authored-by: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com>
* Fix SteamVR polling, VITURE checksums, and fence tracking
Keep manual SteamVR launches polled, discard corrupt VITURE packets, and retire Vulkan fences out of order without blocking submissions at a fixed capacity. Preserve the contiguous completion watermark used by the presenter.
Fix optional Windows launcher configuration and audited helper staging. Add Android, Windows, and native tracker regression coverage.
* Fix SteamVR polling, VITURE checksums, and fence tracking
Keep manual SteamVR launches polled, discard corrupt VITURE packets, and retire Vulkan fences out of order without blocking submissions at a fixed capacity. Preserve the contiguous completion watermark used by the presenter.
Fix optional Windows launcher configuration and audited helper staging. Add Android, Windows, and native tracker regression coverage.
* fix: wireless ADB page names the child-process switch the way Android shows it (#848)
* l10n: refresh stale and untranslated strings in es, fr, ko, ru (#850)
* l10n: refresh stale and untranslated strings in es, fr, ko, ru
- mode_added_art_hint: now mentions Steam then SteamGridDB (all four locales).
- wincomp_needs_installer / wincomp_installers_note: es and ko still described
the old "coming soon" behaviour; align with the current English text.
- summary_remove_game: was still English in all four locales.
Machine-assisted translation; native-speaker review is welcome.
* l10n(es): say registro, not grabación, for the missing installer record
---------
Co-authored-by: ovurrsl <ovurrsl@users.noreply.github.com>
* fix: a failed cloud save recovery no longer ends the app (#846)
The cloud-recovery thread started at every app start had nothing to
catch an error, so one went to CrashHandler, which halts the process
with status 2. In unit tests the thread can outlive the test that
started it, fail on the torn-down preferences, and take the whole test
run down. The error is now logged and the thread ends.
Co-authored-by: Kirk <12691869+KirkPatrickJunsay@users.noreply.github.com>
* fix: an interrupted Linux runtime download resumes instead of starting again (#847)
* fix: an interrupted Linux runtime download resumes instead of starting again
installOnce() asked the downloader to resume but always deleted the archive in its finally block, so the next attempt began at zero. The archive is now named after the release version and checksum, a failed download keeps what it fetched, and archives of other releases (and the old fixed name) are removed. A checksum or extraction failure still deletes the file.
* test: Downloader resumes a cut-off download from the bytes it kept
Starts a socket server that promises the whole file, hangs up part way and then answers a Range request, and checks that the second downloadFile call resumes with the right offset and ends with identical bytes.
* fix: a resumed download discards a 206 that does not start where the kept bytes end
Downloader appended every 206 response to the partial file without
looking at Content-Range. A server or proxy that answers a Range request
with a different offset would leave a corrupt file. Check that the range
starts at the kept length; otherwise delete the partial file and start
again without a Range header.
Adds a test with a server that answers the Range request from offset 0.
---------
Co-authored-by: ovurrsl <ovurrsl@users.noreply.github.com>
* l10n: German, French, Spanish, Italian, Portuguese and Russian for the zRAM, reset-settings and store free-space strings (#849)
* l10n: German, French, Spanish, Italian, Portuguese and Russian for the zRAM, reset-settings and store free-space strings
Adds the strings values-de, values-it and values-pt were missing (14 each) and the six that values-fr, values-es and values-ru were missing. Machine-assisted drafts that follow each file's existing register and terms; native review is welcome.
* l10n: correct missing active swap translations
---------
Co-authored-by: ovurrsl <ovurrsl@users.noreply.github.com>
Co-authored-by: xXJsonDeruloXx <danielhimebauch@gmail.com>
* 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>
* feat: droiddeckctl reports on-screen pacing (recover #843) (#855)
feat: droiddeckctl pacing reports the frames that reached the screen
Reads SurfaceFlinger's timestats for the game's layer (or the session's
SurfaceView) over a capture: frames on screen, fps on screen, the
present-to-present histogram and how many intervals were off the usual
cadence. Records split by a refresh-rate change are summed. A game's own fps
counter counts frames handed over, so it can't show dropped or doubled frames.
Co-authored-by: angelrenefm <17342133+angelrenefm@users.noreply.github.com>
* fix: Steam can restart more than twice in a session (#754)
* fix: Steam can restart more than twice in a session
Every exit 42 counted toward the cap that stops an update which will
not install, and the count was never cleared, so the third restart of
a session ended it however far apart they were. A client that ran for
a minute before asking is not that loop: the count starts again.
* fix: measure the client's run time as it exits
The time spent collecting logs and checking FEX after the client exits
counted toward its run, so a slow cleanup could make a quick exit 42
look like a long one and clear the count.
---------
Co-authored-by: Kirk <12691869+KirkPatrickJunsay@users.noreply.github.com>
Co-authored-by: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com>
* fix: the front end keeps its page when the Fold is folded or unfolded (#832)
* fix: the front end keeps its page when the Fold is folded or unfolded
MainActivity, FileManagerActivity, FilePickerActivity and StoreLoginActivity did not declare the screen-size configuration changes, so folding or unfolding a foldable recreated them and dropped their in-memory state. They now handle orientation, screenSize, screenLayout, smallestScreenSize and density themselves, like SessionActivity already does. uiMode is left out on purpose.
* fix: store login keeps rebuilding its toolbar when the display density changes
StoreLoginActivity builds its toolbar in code with dp-to-pixel values taken at creation time and has no onConfigurationChanged. It no longer declares density in configChanges, so a density change recreates it as before this PR. Size and layout changes are still handled in place.
---------
Co-authored-by: ovurrsl <ovurrsl@users.noreply.github.com>
* Release pointer buttons without replaying stale motion (#803)
* Fix cursor warping on native touch down
* Preserve input cleanup without replaying stale pointer motion
---------
Co-authored-by: siyuan.qsy <siyuan.qsy@alibaba-inc.com>
* l10n: translate the strings added since #284 into zh-CN, zh-HK, zh-TW and ja (#539)
* l10n: translate the 184 strings added since #284 (zh-CN/HK/TW, ja)
The stores, cloud saves, Windows components, Steam touch, desktop
removal and background-downloads strings landed after #284's
translation snapshot, so every one of them fell back to English.
Translate all 184 into Simplified Chinese, Traditional Chinese
(Taiwan and Hong Kong) and Japanese, keeping each locale file's own
vocabulary (工作階段/會話, 解除安裝/卸載, 元件/組件, 設定).
Also fix four Hong Kong strings that kept the simplified 着色器.
* l10n(zh): fix stale and ambiguous strings found in review
Severe: summary_remove_game was untranslated English in all three
files; mode_added_art_hint, wincomp_installers_note and
wincomp_needs_installer still described the pre-#480/#492 English.
Also: distinguish the Setup wizard from Android system settings in
zh-HK/zh-TW (初始設定 / 系統設定 / Android 設定), unify library as
收藏庫, component as 組件 in zh-HK, session as 會話 in zh-HK, account
as 帳戶 in zh-HK, Trending as 趋势/趨勢, Forget as 清除, reword the
re-applied-at-launch, action-failed and already-in-Games strings, and
play as 執行/開啟遊戲 in zh-TW/zh-HK.
* l10n(ja): fix stale and ambiguous strings found in review
---------
Co-authored-by: Dantalian <Dantalian-dev@users.noreply.github.com>
Co-authored-by: xXJsonDeruloXx <danielhimebauch@gmail.com>
* Rebuild and verify Windows VR runtime components
* Rebuild and verify Windows VR runtime components
* Add top, bottom, and centered picture positions for Steam sessions (#871)
* fix: dependency scan ignores folders above the game folder (#859)
* DroidDeck-Proton: get releases from the Droid-Deck org repo
DroidDeck-Proton is now built and released on Droid-Deck/DroidDeck-Proton
(11-9.1 is Latest there), so the Components page, the update check and the
guest installer read releases from the org repo instead of The412Banner's.
* feat: low-latency controller and touch toggles in the session drawer (#808)
* fix: SteamGridDB lookups no longer stick as "no match" after a failure; add a search to the art chooser (#876)
* feat: Steam home wall fills from the signed-in library instead of store picks (#878)
* test: cover GPU family and support classification (#880)
* Fix local builds on Linux failing after the first Comet build (#866)
* feat: sort the store library and installed tabs, and switch between card and list views (#798)
* feat: three-finger tap toggles Steam's on-screen keyboard in game mode (#782)
* fix: keep Quest-patched Turnip as the auto default (#853)
* Fix deploy_local.sh and droiddeckctl not finding a phone connected over wireless debugging (#864)
* fix: keep proot sessions alive when the kernel loses fork events (#457)
* fix(quest): correct desktop and Steam display corruption across sessions (#733)
fix(quest): stabilize desktop and Steam layer presentation
Keep Quest SDR scenes and the black backdrop off the Android Vulkan swapchain regardless of session order or HDR preferences. Only report the first frame after client content is submitted.
Add backdrop lifecycle and first-frame regression coverage. Record the user's successful Quest 3 Test 2 result.
Co-authored-by: xXJsonDeruloXx <danielhimebauch@gmail.com>
* fix: keep SteamVR syscall hooks and report Steam crashes (#905)
* fix: preserve SteamVR syscall hooks
* fix: report Steam crashes through gamescope
* fix: honor glasses pacing and resolution in SteamVR launches
---------
Co-authored-by: connor g <connorsspam1992@gmail.com>
Co-authored-by: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com>
Co-authored-by: Yassine Gherbi <y.gherbi.dev@gmail.com>
Co-authored-by: Resul Övür <92828257+ovurrsl@users.noreply.github.com>
Co-authored-by: ovurrsl <ovurrsl@users.noreply.github.com>
Co-authored-by: Kirk <kirtoy.junsay@gmail.com>
Co-authored-by: Kirk <12691869+KirkPatrickJunsay@users.noreply.github.com>
Co-authored-by: xXJsonDeruloXx <danielhimebauch@gmail.com>
Co-authored-by: angelrenefm <17342133+angelrenefm@users.noreply.github.com>
Co-authored-by: asdf17128 <asdf17128@gmail.com>
Co-authored-by: siyuan.qsy <siyuan.qsy@alibaba-inc.com>
Co-authored-by: Dantalian <wsu091227@qq.com>
Co-authored-by: Dantalian <Dantalian-dev@users.noreply.github.com>
Co-authored-by: The412Banner <the412banner@users.noreply.github.com>
Co-authored-by: The412Banner <205237651+The412Banner@users.noreply.github.com>
Co-authored-by: FX1922 <120828496+FX192@users.noreply.github.com>
Co-authored-by: Muaz Kadan <32595066+muazkadan@users.noreply.github.com>
Co-authored-by: kingokksa <47888451+kingokksa@users.noreply.github.com>
Co-authored-by: Jamie Schenker <jam1esch3nk3r@gmail.com>
Co-authored-by: Jagger15 <jagger2333@live.com>
* Glasses: keep a pending 2D restore and the SteamVR recovery offer, show Play SteamVR only with a picture
* Translate the glasses calibration, XREAL and SteamVR recovery strings
* SteamVR recovery: give a finished teardown time to collect logs before restarting
* Credit the projects the XR glasses support builds on
* Joy-Cons: SteamVR hands from their gyro while SteamVR runs, one combined pad otherwise
* Headsets: settings badge on Play SteamVR instead of a top-right button, both shown only once connected
* Hand tracking: camera-tracked Joy-Cons and bare hands in SteamVR, drawn as white gloves
- Joy-Con movement from the accelerometer (report reordering, per-Joy-Con calibration, zero-velocity updates)
- MediaPipe pose and hand landmarks from the device camera, placement check, per-hand Kalman filter with the Joy-Con
- No controller connected: bare camera hands with Quest-style gestures, 1€ filtered, rendered as a white glove model built from a distance field
- SteamVR safe mode cleared before each start so one crash no longer blocks the driver
---------
Co-authored-by: MaxsTechReview <6025299+maxjivi05@users.noreply.github.com>
Co-authored-by: informalTechCode <informaltechyt@gmail.com>
Co-authored-by: connor g <connorsspam1992@gmail.com>
Co-authored-by: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com>
Co-authored-by: Yassine Gherbi <y.gherbi.dev@gmail.com>
Co-authored-by: Resul Övür <92828257+ovurrsl@users.noreply.github.com>
Co-authored-by: ovurrsl <ovurrsl@users.noreply.github.com>
Co-authored-by: Kirk <kirtoy.junsay@gmail.com>
Co-authored-by: Kirk <12691869+KirkPatrickJunsay@users.noreply.github.com>
Co-authored-by: xXJsonDeruloXx <danielhimebauch@gmail.com>
Co-authored-by: angelrenefm <17342133+angelrenefm@users.noreply.github.com>
Co-authored-by: asdf17128 <asdf17128@gmail.com>
Co-authored-by: siyuan.qsy <siyuan.qsy@alibaba-inc.com>
Co-authored-by: Dantalian <wsu091227@qq.com>
Co-authored-by: Dantalian <Dantalian-dev@users.noreply.github.com>
Co-authored-by: The412Banner <the412banner@users.noreply.github.com>
Co-authored-by: The412Banner <205237651+The412Banner@users.noreply.github.com>
Co-authored-by: FX1922 <120828496+FX192@users.noreply.github.com>
Co-authored-by: Muaz Kadan <32595066+muazkadan@users.noreply.github.com>
Co-authored-by: kingokksa <47888451+kingokksa@users.noreply.github.com>
Co-authored-by: Jamie Schenker <jam1esch3nk3r@gmail.com>
Co-authored-by: Jagger15 <jagger2333@live.com>