Skip to content

Dev - #2

Open
superturtlee wants to merge 208 commits into
superturtlee:devfrom
ravindu644:dev
Open

Dev#2
superturtlee wants to merge 208 commits into
superturtlee:devfrom
ravindu644:dev

Conversation

@superturtlee

Copy link
Copy Markdown
Owner

No description provided.

404-GCross and others added 30 commits June 5, 2026 15:47
* 微调 README_CN.md 与社区支持设备文档措辞

* 修复 GPU-Acceleration_CN 缺少 Rootfs 仓库引用链接

* 翻译 community-supported-devices_CN 新增的 WildKernels OnePlus 设备表格(96行)

* 翻译 community-supported-devices_CN 中 none→无、Working→正常运行

* 翻译社区支持设备状态选项:正常运行/部分可用/不可用

* 修复社区支持设备文档措辞

* 微调社区支持设备文档措辞

* 微调社区支持设备文档措辞

* 微调社区支持设备文档措辞

* 微调社区支持设备文档措辞

* 微调社区支持设备文档措辞

* 微调社区支持设备文档措辞
- monitor, virgl, pulse: explicitly enter droidspacesd via new
  ds_selinux_enter_domain() -- permissive, zero enforced denials
- x11: stays on untrusted_app_27 (app_process requires it);
  dyntransition() loses dead applied_ctx output param
- untrusted_app_27 first in domain trial order to match real Termux
- sepolicy: scope fd/fifo_file rules to untrusted_app_27 (not untrusted_app);
  add audioserver/mediaserver fd use for PulseAudio binder path
Patch default.pa at runtime: load aaudio before always-sink, disable
module-sles-sink and module-console-kit. Add --use-pid-file=false and
--disallow-exit to prevent futex deadlock on Android userdata flock.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
…ndencies and configure PulseAudio for Droidspaces

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
Signed-off-by: ravindu644 <droidcasts@protonmail.com>
…ough

OPOST on the outer line discipline transforms \n->\r\n, corrupting
escape sequences from tmux/vim/claude-code before they reach the user.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
vendor 4.9 devpts patches return EINVAL/EIO on newinstance mounts,
causing silent PTY alloc failure; kernel auto-unlocks when needed

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
… buf

- signalfd(SIGCHLD) replaces 100ms poll-waitpid busy loop in handle_session
- signalfd(SIGWINCH) replaces signal handler + 200ms epoll timeout in client
- drop redundant poll() probe before recv_frame_hdr in client frame loop
- shrink cmdline log buffer from 16KB to 512B stack allocation

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
all four functions were identical modulo which ds_config bool field
they tested. collapse into one offsetof-based scanner; keep thin
compat wrappers so existing call sites are unchanged

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
…own_lines

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
3 identical ~25-line stop functions (x11/virgl/pulse) collapsed to
one-liner wrappers; kill/wait/unlink logic lives in one place now

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
Move Android-specific sources (android, x11, virgl, pulseaudio) into
src/android/, network sources (network, netlink, iptables, dhcp) into
src/net/, and all headers into src/include/.

Redundant prefixes/suffixes dropped: ds_ and -android stripped where
the subdirectory name already conveys the context.

Update Makefile SRCS paths, -I flag (now -Isrc/include), VERSION grep
path, and add mkdir -p to the compile rule for object subdirs.
Update src/socketd/Makefile -I and fix api_server.cpp's relative
Support NixOS-specific su path to run su correctly in NixOS containers.
…stale runtime configuration

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
Currently translated at 100.0% (467 of 467 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (467 of 467 strings)



Translate-URL: https://hosted.weblate.org/projects/droidspaces/strings/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/droidspaces/strings/zh_Hant/
Translation: Droidspaces/Strings

Co-authored-by: Jung Chi Wang <snowwolf725@gmail.com>
Co-authored-by: MengHanLOVE <2193438288@qq.com>
Inject libskcodec.so into LD_PRELOAD (lib64 > lib priority) to fix
module-sles-sink dlopen failure on One UI 6.1+; install libandroid-stub
and disable module-suspend-on-idle in setup-termux.sh to fix PA futex hang.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
Signed-off-by: ravindu644 <droidcasts@protonmail.com>
replace scattered getuid() checks with a single gate after daemon proxy;
rename is_stateless_cmd -> is_no_root_cmd, add 'check' to exempt list

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
Signed-off-by: ravindu644 <droidcasts@protonmail.com>
replace blocking write_all(master) with non-blocking write + dynamic wbuf;
flush via EPOLLOUT, suspend conn EPOLLIN at 192KB, resume at 64KB

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
Signed-off-by: ravindu644 <droidcasts@protonmail.com>
* build: add patched BusyBox as submodule

* build: enable socketd backend bridge by default
Signed-off-by: ravindu644 <droidcasts@protonmail.com>
…y applied post-extract fixes

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
Acquire PARTIAL_WAKE_LOCK then fire ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
(API 23+); fallback to ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS for OEMs
that block the direct dialog (MIUI etc.). Add manifest permission.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
Add receive/send timeouts to accepted socketd backend bridge
connections so a partially written request cannot block the privileged
bridge indefinitely.

Also replace the bridge-specific same-EUID authorization rule with the
same peer authorization model used by the main daemon: allow root, or
allow peers that are members of the droidspaces group. This keeps the
backend bridge aligned with the existing Droidspaces local privilege
boundary instead of granting access to every process running under the
same UID.
ravindu644 and others added 25 commits July 26, 2026 18:49
ContainerCommandBuilder.buildUptimeCommand was @deprecated in favor of
buildUsageCommand and has no remaining callers. Delete it.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
The identical Build.SUPPORTED_ABIS[0] -> arch when-ladder existed three times
(BinaryInstaller.getArchitectureSuffix/getArchitectureName, RootfsRepository.deviceArch).
Extract one DeviceArch util (suffix() + displayName()); the existing functions now
delegate to it, so callers are unchanged.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
FilePickerDialog ran root Shell.cmd("[ -d \"$targetDir\" ]") and Shell.cmd("ls -F \"$path\"") with the path only double-quoted, so a directory/path containing ", $(...) or backticks executed as root when browsed. Route both through ContainerCommandBuilder.quote() (POSIX single-quote escaping).

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
getUsage() interpolated ContainerInfo.rootfsPath (read verbatim from the config file, never validated) double-quoted into a root busybox stat command; $(...) / backticks would run as root. Quote via ContainerCommandBuilder.quote().

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
cleanup() ran Shell.cmd("rm -rf $path 2>&1") completely unquoted as root; paths derive from the container name via the weak sanitizeContainerName. Quote via ContainerCommandBuilder.quote(). (sanitizeContainerName hardening deferred.)

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
…-c payload

The terminal built su -c 'droidspaces -n "$name" enter $user' escaping only double quotes; $user (sourced from the container's /etc/passwd, unvalidated) was spliced raw. Validate containerName against the creation charset (letters/digits/space/_.- so normal names incl. spaces still work) and containerUser against a metachar-free allow-list (fallback root); an unsafe name opens a bare root shell instead of an injectable payload.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
allowBackup="true" with no dataExtractionRules let app-private data (PreferencesManager cache incl. custom rootfs-repo URLs, cached container defs) be exfiltrated/injected via ADB or cloud backup/restore. Set allowBackup="false".

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
…ffic

The rootfs supply chain (manifest fetch + tarball download, incl. user-added custom repos) had no scheme enforcement; only the implicit platform default blocked http. Add res/xml/network_security_config.xml (cleartextTrafficPermitted=false) referenced from the manifest to block cleartext app-wide, and reject non-https URLs in RootfsRepository.httpGet and PreferencesManager.addCustomRepo.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
The AccentColorPicker section-header ListItem omitted a container color, so it
rendered on the opaque default surface and looked darker than the surrounding
Settings rows (Language / SwitchItem), which use a transparent container. Set
containerColor = Color.Transparent to match. Surfaced by post-refactor testing
(REFACTOR_TEST_PLAN §12); verified on-device.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
… corrupted

The Check Requirements button runs the droidspaces binary, but was only gated on
root availability — so with the backend nuked/corrupted it stayed tappable and the
check failed. Gate it on the backend status too (Available/UpdateAvailable) and
force a fresh backend re-check on entering the screen so a binary removed after the
last check is detected. Surfaced by post-refactor testing (REFACTOR_TEST_PLAN §2);
verified on-device.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
…-op BootReceiver

The app declared RECEIVE_BOOT_COMPLETED and a BootReceiver that was a documented
no-op — autostart is handled by the Magisk module's service.sh, not the app. Drop
the permission, the receiver declaration, and the BootReceiver class to shrink the
attack surface and remove the dropper-pattern smell scanners flag. Reversible if
app-side autostart is added later.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
validateRootfsTarball returned early (installing anyway) if the validator script
could not be loaded or made executable — a fail-open gate on a rootfs that is later
run as root. Treat validator load/chmod failure as a validation failure that aborts
the install, matching the existing throw on a failed check.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
…fig values

Free-text config fields (dnsServers, staticNatIp, customInit, tx11/virgl extra
flags, privileged, gateway names) are written verbatim as key=value lines into the
root-owned container.config parsed by the privileged backend — a newline injects an
extra trusted key. Add ValidationUtils.validateConfigValues (rejects ISO control
chars; excludes multi-line envFileContent) and enforce it in both write paths,
installContainer (create) and updateContainerConfig (edit). Compose singleLine
fields already block newlines in the UI; this covers non-UI/import paths.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
… config load

Defense-in-depth for the container-name -> root path sinks: route every
container-derived path in ContainerManager's root Shell.cmd calls (cat/cp/chmod/
rm -rf/test on config, .env and container dirs) through ContainerCommandBuilder.quote()
instead of bare double-quotes, and re-validate the name in parseConfig — a container
whose on-disk name carries shell metacharacters is skipped (logged) before it can
reach a root command. Uses a charset-only isSafeContainerName (no length limit) so
over-length-but-safe legacy names still load; sanitizeContainerName's transform
contract is unchanged (rejecting-instead-of-transforming deferred as behavior-risky).

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
…vity leak

A running TerminalSession keeps a reference to its client (the UI's TerminalBackEnd,
which strongly holds the Activity + TerminalView). Backgrounded sessions live in the
long-lived TerminalSessionService, so a disposed terminal screen leaked its Activity
and whole view tree. Add an app-scoped NoOpTerminalSessionClient and a
SessionBinder.detachAllClients(); ContainerTerminalScreen's onDispose now detaches
before unbinding. Sessions keep running; the screen re-attaches its own client via
updateTerminalSessionClient on re-entry (already done in the AndroidView factory).

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
…ewModel

The four container operations (export, uninstall, start/stop/restart, sparse
migrate/resize) and their state (runningOperationContainer, containerLogs,
showLogViewerFor, uninstallState, uninstallLogsDialog, lastErrorContainer) lived
as suspend functions + remembered state inside the ContainersScreen composable,
doing root Shell.cmd, asset deploy, command building and content-URI streaming.
Extract them into a new ContainerOperationsViewModel; the composable now observes
its state and delegates, passing UI concerns (snackbar/list-refresh/usage-clear)
back as callbacks. Commands, quoting, TerminalSessionService intents, refresh and
SELinux-status calls, dialog sequencing and log streaming are unchanged. Verified:
compileDebugKotlin.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
…l.performInstallation

InstallationScreen's LaunchedEffect ran the whole backend install/update
orchestration inline — root Shell.cmd (rm -rf module, test -f), BinaryInstaller/
ModuleInstaller/SymlinkInstaller, daemon-mode preference — mutating seven remembered
state vars. Move it into AppStateViewModel.performInstallation() with the state
hoisted onto the ViewModel; the composable now just calls it from LaunchedEffect and
renders the observed state. Steps, ordering, daemon/symlink handling and post-install
refresh are unchanged. Verified: compileDebugKotlin.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
The ContainerCard call site passed 11 separate lambdas. Introduce a
ContainerCardActions data class and pass one stable object; ContainerCard
destructures it internally so the body is unchanged. No behavior change.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
The container list used Column().verticalScroll() + forEach, re-laying-out and
reallocating every row on each recomposition. Switch to LazyColumn with
items(containers, key = { it.name }); tap-to-collapse, spacing, FAB, Install
button and pull-to-refresh preserved.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
The install-wizard ViewModel resolution block (viewModel scoped to the
ContainerName back-stack entry) was copy-pasted verbatim across 4 wizard routes.
Extract a private wizardScopedViewModel(navController, backStackEntry) helper and
use it. No behavior change.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
Replace SettingsScreen's hand-rolled SharedPreferences.OnSharedPreferenceChange
listener (in a DisposableEffect) with reactive PreferencesManager.daemonModeFlow /
symlinkEnabledFlow (callbackFlow over the prefs) collected with
collectAsStateWithLifecycle(). Same toggle behavior, persistence and on-disk sync
(DaemonModeRepository); the flows also observe writes from syncDaemonModeFromDisk.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
- WelcomeScreen / InstallationSummaryScreen: drop the now-unused 'btnShape' vals
  left behind when DT-4 extracted PrimaryActionBottomBar.
- InstallationScreen: drop a redundant elvis on the (smart-cast non-null)
  errorMessage introduced by the DT-6 move.
No behavior change; compileReleaseKotlin is now warning-clean for these files.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
The systemd/OpenRC/procd service list only switched filter categories (Running,
Enabled, Disabled, Abnormal, Static, All, Masked) by tapping a chip. Wrap the list
in a HorizontalPager (one page per filter) so categories can also be swiped
left/right: the pager and chip row stay in sync (tap animates, swipe selects), the
selected chip auto-scrolls into view, and far hops jump directly instead of flipping
through every intermediate page. Search still overrides with a single results list.

Signed-off-by: ravindu644 <droidcasts@protonmail.com>
The monitor never read the console PTY master in background mode, only
foreground did (via console_monitor_loop). Once a container's init wrote
past the ~64 KiB PTY buffer, /dev/console blocked forever in
n_tty_write and the whole container wedged permanently.

Add the master to the monitor's existing heartbeat poll loop and drain
it continuously, appending output to a per-container console log. This
both fixes the deadlock and recovers previously-lost background boot
logs.
* Fix launcher icon blurry on Xiaomi tablet dock

Change ic_launcher_foreground.xml width/height from 24dp to 108dp to match
adaptive icon canvas size. This fixes the blurry icon issue on Xiaomi tablet
desktop and dock bar where the launcher renders the vector at its intrinsic
size before scaling up.

* Trigger CI build for testing
@ravindu644
ravindu644 deleted the branch superturtlee:dev July 26, 2026 15:04
@ravindu644
ravindu644 deleted the dev branch July 26, 2026 15:04
@ravindu644
ravindu644 restored the dev branch July 26, 2026 15:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.