mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-11-11 02:51:10 +00:00
playstore
2080
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4798ee84d5 |
fix(playstore): translate the strings merged from main and clear release lint
Every locale gets the 77 strings that main added without translations. The percent HUD labels are marked unformatted, O_CLOEXEC is only used from API 27, and the top-desktop key route matches the other RestrictedApi call sites. |
||
|
|
95cb9159de |
Merge main into playstore for 0.6.9.2 (version code 20)
Brings the main fixes and features since
|
||
|
|
bf693d7f71 |
fix: Auto picks the upstream RADV pair on Xclipse 950 and 960 (#2158)
* fix: Auto picks the upstream RADV pair on Xclipse 950 and 960 * fix: Auto reads the Xclipse model after the Vulkan query * fix: Auto treats an unnamed Xclipse like the 950 and 960 * fix: Auto reads any three digit Xclipse model number |
||
|
|
4cbd7722f8 |
feat: the PowerVR runtime is a downloaded add-on pack, not bundled in the APK (#2157)
* feat: the PowerVR runtime is a downloaded add-on pack, not bundled in the APK * fix: a stopped session cancels the PowerVR pack download * fix: a session stopped during runtime unpacking ends before staging * fix: a failed PowerVR pack download ends the session with a message |
||
|
+1 |
3733c50902 |
feat: non-Adreno graphics stack (Venus, open driver pairs, gamescope patches) (#2029)
* Retain compositor resources when GPU completion is unconfirmed * Stop quarantined GPU callers before retries and mapped writes * Support Android hardware-buffer presentation over Wayland * Support PowerVR swapchains and linear image imports in Gamescope * Bundle verified PowerVR graphics components through existing build preparation * Detect and select the system Vulkan backend on PowerVR * Apply PowerVR Steam and game compatibility during normal launches * Show PowerVR support through existing driver and component controls * Update existing hardware guidance for system Vulkan support * Import the shared system Vulkan readiness check * Discover and propagate the actual PowerVR render node * Prune obsolete PowerVR runtimes after guest processes exit * Retain external DMA-BUF ownership after GPU quarantine * Name the PowerVR HAL selection explicitly * Isolate component UI tests from application startup * Cover the inherited FEX preset in PowerVR profile tests * Log test worker failures for CI diagnosis * Remove temporary test logging after diagnostic CI * Prefer system dependencies for the Android Vulkan loader * Capture raw stderr before test worker termination * Remove the temporary test worker crash probe * Import pinned DXVK recipe prerequisite from PowerVR PR570 Copy only the standalone build recipe, source pin, BC-format prerequisite and presentation-sync patch/check from wallentx/DroidDeck at |
||
|
|
f4e5032b7d | fix(fex): skip local patches already in the FEX release (#2152) | ||
|
|
c8a76e7cce |
perf(agent): run diagnostic cleanup off startup thread (#2147)
* perf(agent): run stage cleanup off startup thread * fix(agent): preserve active diagnostic stages * test(agent): verify active stage locks cross-process |
||
|
|
6a681bcbc2 |
docs: clarify DX12 budget consumers and physical limits (#2148)
* docs: clarify DX12 budget consumers and physical limits * docs: record controlled Thor gameplay limits |
||
|
|
cd452e2b60 |
fix: upload GOG cloud saves in Galaxy's gzip + metadata format (#1952)
fix: upload GOG cloud saves in Galaxy's gzip format |
||
|
|
5971b91ed4 |
fix: an unplugged game drive falls back to internal storage (#1913)
* fix: an unplugged game drive falls back to internal storage When the drive chosen for game storage is not connected, installs, sessions and the install picker use internal storage instead of failing with "Game storage is unavailable". The saved drive is kept and used again once it is plugged back in. * fix: store installs set to external use internal storage while the drive is unplugged With default storage set to external, a missing drive or folder no longer stops installs at the location dialog or leaves the Epic launcher pointing at it. Installs go to internal storage and switch back to the drive once it is connected again. * fix: external installs do not move to another card while the saved drive is unplugged * fix(storage): verify saved volume is mounted * fix(storage): reject unknown external volumes --------- Co-authored-by: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com> |
||
|
|
906e60a042 |
feat(desktop): show programs installed by Windows installers (#2146)
* Desktop: programs a Windows installer adds get a menu entry and desktop icon Opening a Windows installer on the desktop runs it with Proton in a prefix of its own (droiddeck-proton-run's "own" prefix). Proton's menu builder turns the installer's Start Menu links into .desktop files, but keeps them in the prefix's drive_c/proton_shortcuts with a Windows .lnk path as Exec, and nothing outside the prefix pointed at the installed program: Nexon Launcher installed fine on an AYANEO Pocket FIT Elite and could only be found by browsing the hidden compatdata folder. droiddeck-desktop-programs reads proton_shortcuts in every prefix that is neither a Steam game's nor a current Steam shortcut's, resolves each link to its program inside the prefix, and writes a menu entry that opens it with droiddeck-open, so it runs in that same prefix, with the icon Proton extracted. A program whose installer also put a link on the Windows desktop gets a desktop icon once; one the user deletes is not put back. Entries go away with their program; uninstallers get none. It runs when the desktop starts and after droiddeck-open finishes a Windows program. * Desktop programs: only programs that run in their prefix, Windows argument rules, one refresh at a time A link resolved through Proton's Z: mapping could name a program outside the scanned prefix, and droiddeck-open would then run it in another one. A program is now listed only when droiddeck-proton-run's prefix_of puts it in the prefix it was found in. Shortcut arguments were split with shlex, so a Windows argument with an apostrophe raised and stopped the whole refresh; they are now split by the Windows command-line rules. The desktop start and the end of a Windows program can refresh at the same time and race on the same temporary files; refreshes now take turns on a lock beside the placement record. * Desktop programs: extract the script at session start SessionFiles lists the overlay scripts the app copies into the runtime; droiddeck-desktop-programs was missing, so a real build would never have installed it and check_session_assets failed the build. * Desktop programs: a compatdata folder it cannot read changes nothing Any error listing steamapps/compatdata made the refresh see no prefixes, so it removed every program entry and forgot which desktop icons it had placed; the next good run then put back icons the user had deleted. Only a missing compatdata now means there is nothing installed; any other read error leaves the menu, the desktop and the placement record as they were. * Desktop programs: an unreadable shortcut or desktop folder changes nothing os.path.isdir and glob read an unreadable proton_shortcuts or Windows desktop folder as empty, so the refresh dropped that prefix's entries and placement records and a later run put back icons the user had deleted. Those folders are now listed directly: a missing one is still empty, and any other error leaves the menu, the desktop and the record as they were. * Desktop programs: only a missing file reads as absent read(), link_target() and host_path()'s letter-case lookup turned any error into "absent", so an unreadable placement record read as empty and brought back icons the user had deleted, and an unreadable shortcut or link dropped its program's entry. A missing file, a wrong file type and a malformed link still read as absent; any other error now reaches main(), which leaves the menu, the desktop and the record as they were. * Desktop programs: keep the placement record true when a run fails part way The placement record was read after the menu was already rewritten, so an unreadable record changed the menu although the run reported it had not. It is now read first. When writing desktop icons failed part way, the icons already written were not recorded, and the next run recreated any of them the user had deleted. The record is now written from the icons that exist after the attempt, icons are written in a fixed order, and a failed write leaves no temporary file on the desktop. os.path.exists and isfile also read a program whose path cannot be reached as missing; a stat that fails only because the file is absent now counts as missing, and any other error leaves everything as it was. * Desktop programs: leave the menu alone when Steam's shortcuts cannot be read The list of Steam shortcuts comes from a reader that treats an unreadable or damaged shortcuts.vdf as having no shortcuts, so a Steam shortcut's prefix could get a menu entry and a desktop icon of its own. The file is now checked first: a missing one still means no shortcuts, and any other read or parse failure leaves the menu and the desktop as they were. * Desktop programs: an unreadable Steam account or empty shortcuts file also stops the refresh account_dir takes an unreadable loginusers.vdf or userdata folder as missing, so the shortcuts check could be skipped and a Steam shortcut's prefix still get its own entry. Both are now read first, and an access error leaves the menu as it was. An empty shortcuts.vdf is now parsed like any other, so it stops the refresh too, the same way droiddeck-steam-shortcuts refuses to rewrite it. --------- Co-authored-by: K11MCH1 <81425424+K11MCH1@users.noreply.github.com> |
||
|
|
9d2580d502 |
perf: reclaim launcher memory earlier under pressure (#2138)
* perf: reclaim launcher memory under system pressure * docs: record Caravan save-load OOM with spare swap * fix: wait for completed reclaim before increasing backoff |
||
|
|
6a5722c6d1 |
fix(preload): answer NETLINK_ROUTE queries inside a session (#2141)
* fix(preload): answer NETLINK_ROUTE queries inside a session ip(8) could not run in a session: the app's SELinux domain has no netlink_route_socket bind permission, so iproute2 failed at bind and never saw the link that getifaddrs() and /proc/net already expose. Serve NETLINK_ROUTE from the same etc/droiddeck-net snapshot: an AF_UNIX socketpair backs the netlink fd, link/addr/route dumps and route get are synthesised, writes return EPERM, and multicast subscriptions keep failing with EACCES so consumers that wait for link events keep their fallback. Replies carry the port id reported by getsockname() and recvmsg() rewrites the source address to AF_NETLINK/pid 0. iproute2's dump loop requires both before it accepts a message or NLMSG_DONE; when either is missing every message is skipped silently and the process blocks in recvmsg(). * fix(preload): keep socket() and send() semantics for emulated netlink * fix(preload): deliver netlink replies with the caller's blocking mode * fix(preload): preserve NETLINK_ROUTE protocol and fd semantics - Send ACKs for successful queries and honor NETLINK_CAP_ACK - Reject unsupported subscriptions and apply socket timeouts - Track socket identity and shared references across dup and close - Support kernel connect and rewrite recvfrom source addresses - Resolve local and connected routes before default gateways - Add netlink and iproute2 regression tests * fix(preload): handle netlink request limits and socket lifecycle - Collect large sendmsg requests without falling back to UNIX sockets - Reject oversized replies explicitly instead of returning partial results - Allocate unique port IDs and reject duplicate bindings - Honor socket flags and restore inherited sockets across exec - Validate socket types and report netlink socket identity - Replace the fixed socket table with a dynamic registry - Add regression tests for batching, port conflicts and exec inheritance * fix(preload): optimize netlink tracking and support link name queries - Add lock-free fd tracking to bypass netlink locks on ordinary sockets - Move descriptor restoration to initialization and explicit discovery paths - Support RTM_GETLINK lookups via IFLA_IFNAME with correct error codes - Add regression coverage for hot-path overhead and name-based queries * fix(preload): accept unterminated netlink interface names - Copy IFLA_IFNAME into a bounded, NUL-terminated buffer before lookup - Match kernel string length validation and ERANGE errors - Add regression coverage for unterminated names and boundary cases * fix(preload): pin peers for netlink replies * fix(preload): make autobind idempotent * fix(preload): isolate forked netlink cleanup * fix(preload): avoid interposed fd scans * perf(preload): skip PID checks for untracked fds * fix(preload): verify peer before replay --------- Co-authored-by: uubooster-team <uu.booster@service.netease.com> |
||
|
|
b875b39905 |
fix(input): release held mouse buttons and keys when the session loses focus (#2139)
* fix(input): release held mouse buttons and keys when the session loses focus A mouse button or key held in the guest stayed down when another window took focus or pointer capture ended before the release, because the release went to that window. A game that hides the cursor while a button is held, such as mouselook in World of Warcraft, then kept turning the camera with the cursor gone until the button was pressed again. Buttons sent to the guest are now tracked like keys, and every held button and key is released when the session window loses focus or pointer capture, and when picture-in-picture opens. * fix(input): release a held button where it was pressed A button pressed through the compositor was released through the raw mouse channel if that channel turned on while it was held, and the reverse, so the guest kept it down. Each held button now remembers where it was pressed. A scroll-touch drag is also cancelled when the session loses focus. * fix(input): release trackpad buttons on focus loss --------- Co-authored-by: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com> |
||
|
|
ecedf131e0 |
fix(game-env): allow Supergiant mscoree fallback (#2143)
* fix(game-env): allow the builtin mscoree for Supergiant .NET crash reporter * test(game-env): cover Supergiant mscoree fallback --------- Co-authored-by: xor <31260844+randornot@users.noreply.github.com> |
||
|
|
8ac5652131 |
fix(components): a native-only override falls back to builtin when the prefix has no native DLL (#2142)
* fix(components): a native-only override falls back to builtin when the prefix has no native DLL A component that asks for a DLL native-only (for example .NET 4.8's mscoree=n) left the DLL unloadable when its native copy never reached the prefix. On ARM64 prefixes the .NET installer leaves Wine's builtin mscoree in system32, so every program that needs .NET exited at launch with 'mscoree.dll not found'. At launch, an override of n for a DLL whose system32 or syswow64 copy is missing or is Wine's own (a link into the Proton build, or a builtin or placeholder stub) becomes n,b, and the session log says so. A real native copy is still loaded first, and the saved component state is unchanged, so the override returns to n once the native DLL is there. * Treat any prefix symlink as builtin when checking native overrides * Treat an unreadable prefix DLL as missing for native overrides |
||
|
|
5624b483fb |
fix(input): reach full guest screen with glasses pointer (#2145)
fix: the glasses pointer reaches the whole guest screen Absolute input was clamped to the letterboxed picture rect computed for the phone view, while the compositor reads the input space against the glasses output. With different shapes that limited the guest pointer to a middle band of the scene, so the bottom and top edges were unreachable. Send absolute pointer positions as the full-view fraction (the compositor already clamps to the scene) and use the whole view for the touchpad bounds and relative scale while the glasses own the output. Fixes #2055 Co-authored-by: Moroni Granja <moronigranja@gmail.com> |
||
|
|
d64205ba5b |
fix: report Vulkan memory budgets without rejecting allocations (#2014)
Extend the VRAM setting to Vulkan memory-budget reports for DXVK and D3D12 while preserving real heap capacity and allocation results, removing the hard rejection that caused game crashes in FIT and Discord tests. |
||
|
|
df76f66e8f |
gamescope: ship p20 so the EA sign-in stays above the launcher splash (#2045)
#2037 added gamescope patch 0126, but the app does not build gamescope. It stages the prebuilt binary pinned in `tools/gamescope/release.env`, which is still `gamescope-3.16.29-p19`, built on Oct 29 before the patch existed. A fresh install of a main build therefore still draws the EA Steam Launcher's "Authenticating…" splash over the EA "Verify your identity" sign-in. The APK of main |
||
|
|
da851dae22 |
fix(input): taps land where touched while a game holds the pointer (#2133)
* fix(input): taps land where touched while a game holds the pointer Games that hide the system cursor and draw their own, such as Stardew Valley, hold the pointer the same way first-person games do. Every touch on the default touch mode then went through the touchpad, so a tap clicked wherever the cursor already was: tapping New opened Load, and a tap after Back could press Exit. A touch now stays a direct touch while the pointer is held. A tap clicks where the finger is, and once a swipe moves past the touch slop it turns the camera with relative motion as before. Touchpad mode is unchanged. * fix(input): keep the swipe anchor when the first finger lifts When the first finger of a locked-pointer swipe lifts and another stays down, the next move is reported for the remaining finger. The anchor now moves to that finger, so the camera does not jump. |
||
|
|
7a78d2b66b |
fix(agent): secure and refresh unrooted log exports (#2131)
## Summary - Keep raw diagnostic staging in private cache and give each exported archive a unique request directory. - Remove that request directory after the CLI pull, including failed transfers. - Replace files from the previous extracted snapshot while preserving unrelated destination files. - Document that the old rooted-device fallback is not scrubbed. Follow-up to #2061. The refreshed export tests now cover independent archive outputs and stale snapshot replacement. ## Validation - `wsl python3 -m unittest tools.tests.test_droiddeckctl` — 49 passed. - `:app:testDebugUnitTest -x buildVkBridgeServer --tests com.droiddeck.launcher.session.SessionLogShareZipTest.anArchiveCanBeWrittenOutsideTheShareFolder` — passed. - `git diff --check` — passed. |
||
|
|
604a01d353 | fix: map log destination errors | ||
|
|
e8ffe1164f | fix: detect D3D12 capabilities and remove redundant game workarounds (#2134) | ||
|
|
1ae37055c9 | fix: preserve diagnostic staging failures | ||
|
|
a431c40b1b | fix: preserve per-file diagnostic failures | ||
|
|
285ff7956b | test: cover independent agent log exports | ||
|
|
64f114c96f | fix: detect graphics capabilities and drop redundant title overrides | ||
|
|
9f22f63222 | test: verify independent log export paths | ||
|
|
0bb8384c76 | fix: avoid unsupported ray tracing on Stellar Blade startup | ||
|
|
671c4a623f | test: assert cleanup after failed log pull | ||
|
|
dfc0fd4340 | fix: harden diagnostic staging lifecycle | ||
|
|
11c0763fba | fix: preserve log cleanup failures | ||
|
|
ff686d7c3b | fix: expire stale log exports safely | ||
|
|
4765644451 | fix: harden log export transactions | ||
|
|
718712eb01 | fix: secure and refresh unrooted log exports | ||
|
|
ca0689d254 |
fix(steam): default listed titles with a bundled arm64 Linux build to FEX (#2126)
Refs #1774. Maldhalla (4385780) ships its x64 and arm64 Linux builds side by side in one depot. Its launcher starts the arm64 build when it runs on an Arm host, natively or as an x86 shell under FEX. Steamworks offers no arm64 value for a launch option's CPU architecture, so the appinfo still reads `oslist` linux+windows and `osarch` 64. `native_targets()` therefore leaves the title on the Proton ARM64 default, which runs the Windows build. This PR adds `FEX_DEFAULT_APPS`, an explicit allowlist (the opt-in suggested in #1774). A listed title defaults to `droiddeck-fex` instead of `NATIVE_CHOICE`. Nothing else changes: - A player's own pick is kept, as before. - Unlisted titles keep today's behaviour, including the Factorio native-choice case. On the Snapdragon 8+ Gen 1 tablet from #1774, our benchmark scores 8–11 with the Windows build under Proton ARM64 and above 100 with the native arm64 build. Test: `ProtonDefaultTest.test_a_listed_title_with_a_bundled_arm64_linux_build_defaults_to_fex` in `tools/tests/test_game_environment.py`. It fails without the change. `ProtonDefaultTest`, `test_droiddeck_proton_default`, `test_steam_compat_mapping`, `test_appinfo_lookup` and `test_steam_compat_live` pass. |
||
|
|
7e0859872b |
fix(steam): keep a cleared FEX default for a listed title as a native choice
A listed title whose automatic FEX mapping the player clears now records the empty mapping as a native choice, as titles with NATIVE_CHOICE do, instead of getting FEX again on the next run. |
||
|
|
28d4f58f33 |
fix(steam): default listed titles with a bundled arm64 Linux build to FEX
Steamworks has no arm64 launch-option architecture, so a title that ships x64 and arm64 Linux builds side by side still reads as osarch 64 and gets the Proton ARM64 default. List such titles in FEX_DEFAULT_APPS so they default to Linux x86 (FEX), whose launch runs the bundled arm64 build. A player's own pick is kept, and unlisted titles are unchanged. Refs #1774 |
||
|
|
ee0d8d9997 | fix: guard session clock logger lifecycle | ||
|
|
5805631be5 |
Session logs: record clocks, thermal status and battery temperature in every session
ClockLogComponent was only created inside startVkBridge(), so it never ran on Adreno. Create it for every session (clocks.log, was vkbridge-clocks.log) and append the battery temperature from ACTION_BATTERY_CHANGED to each sample. Part 1 of #1837. |
||
|
|
baf7d90df9 |
build: drop the unused androidTest variant so the VS Code Kotlin import works
The project has no instrumented tests. The Kotlin extension's Gradle import reads the debugAndroidTest outputs without running their tasks and fails. |
||
|
|
cb3c3cb2c9 |
Added games: a reused ranking is not remembered as a fresh walk
A ranking a scan took from added-games-scan.json was also put in the 60-second in-memory cache with the current time, so for the next minute single(), addFolder() and the exe picker, which ask for a fresh walk, got a ranking that could be a week old. Kept rankings are now returned without entering that cache, so it only ever holds rankings from real walks. |
||
|
|
df60fdb194 |
Added games cache: skip bad records, expire names on read, retry failed saves
A record whose fields could not be decoded threw while the cache loaded, and since every scan loads it first, one bad record blocked every scan; each record is now decoded on its own and skipped if it is malformed. name() returned names older than a week that were still in memory; it now applies the same age limit as rank(). save() cleared its dirty flag before writing and called startWrite outside its try, so a write that failed was never retried and could replace the scan's result with an exception; a failed write now leaves the cache dirty and is tried again on the next save. |
||
|
|
93923e125d |
Added games: one scan at a time, and keep what it found across launches
Every Steam session scans the added games before the Linux side starts, walking each game folder for its exe and reading the exe's version info. On an AYANEO Pocket FIT Elite with 40 games on an exFAT SD card that walk took 10 s with a warm cache and up to 155 s after Android had dropped it, and the front end's art pass and library load ran the same scan at the same time, so the session waited on all of them. Scans now run one at a time, so a waiting scan reuses what the one before it just found. Each game folder's exe ranking and identified name are kept in added-games-scan.json; a scan reuses a ranking while the folder's modification time is unchanged, its first exe still exists and it is under a week old, and walks the folder again otherwise. The exe picker, single game refreshes and adding a folder still walk the folder fresh. |
||
|
|
fcbd45453f |
Steam imports: read only the linked manifest, and leave staged ones alone
seed_install read the app's manifest from every library before checking that it was the linked DroidDeck install, so a manifest in another library that is not UTF-8 raised past the caller and stopped routing for later games. It now returns before reading anything but the linked manifest. An untouched manifest from an older version was migrated even while steamapps/downloading/<appid> existed; that migration now waits until Steam is not staging the app, like the rewrite of a queued import. |
||
|
|
1ec1c20be1 |
Steam: imported games with no known build update only when launched
An added game the account owns is linked into Steam as DroidDeck-<appid>. When the folder carries no Steam build, Steam marks it Update Required and checks every file before updating. That check reads the whole game, and an interrupted one starts over, so on an SD card it ran again in every session and kept the card busy: Lords of the Fallen (33 GB) restarted 51 times in a day on an AYANEO Pocket FIT Elite. The manifest for such an import now asks Steam to update the game when it is launched. Imports that Steam already rewrote, but whose update has not started, switch from "always keep updated" to "update when launched"; a priority of 2, an update in progress, or an import with a recorded build is left alone. |
||
|
|
ccab14384d | test: isolate unrooted log archive output | ||
|
|
8cc652e812 |
fix(droiddeckctl): address review on logs latest
Stream each archive entry to disk instead of reading it into memory, refuse an archive from a session that started after the state call, and delete the exported zip from shared storage once it has been pulled. |
||
|
|
2fb066507a |
fix(droiddeckctl): logs latest works without root
`logs latest` pulled the session folder under getFilesDir(), which adb cannot read on an unrooted device, so it always failed with "Permission denied" and droiddeck-scenario kept no logs for failed runs. The agent bridge gets a `logs` method that writes the Share logs archive to the app's external files folder (agent-logs/), and droiddeckctl pulls that zip and unpacks it into the destination with the session's files at the top, as before. Builds without the method still get the old pull. |
||
|
|
4b6cba0a6d | fix(l10n): mark Russian percent string unformatted |