128 lines
4.8 KiB
Nix
128 lines
4.8 KiB
Nix
{ ... }: {
|
|
flake.nixosModules.desktopWaydroid =
|
|
{ config, lib, pkgs, ... }:
|
|
# `virtualisation.waydroid.package` defaults to `waydroid-nftables` when `networking.nftables.enable`
|
|
# is true — required on recent kernels where legacy `ip_tables` / `waydroid-net.sh` (iptables) fails
|
|
# with `waydroid session start` (nixpkgs#459520).
|
|
let
|
|
cfg = config.chiasson.desktop.waydroid;
|
|
in
|
|
{
|
|
options.chiasson.desktop.waydroid = {
|
|
enable = lib.mkEnableOption ''
|
|
Waydroid + synced base props / nav mode. Needs Wayland; desktop hosts only. This module also
|
|
sets `networking.nftables.enable` (default) so NixOS uses `waydroid-nftables` — needed on newer
|
|
kernels where `waydroid-net.sh` / iptables fails. For **Google Play** apps (e.g. Hot Wheels
|
|
Showcase), run `sudo waydroid init -s GAPPS -f` once after the first `nixos-rebuild` (or reset
|
|
the container if you already initialized without GAPPS); then sign in and install from the Play
|
|
Store. If `dnsmasq` reports port 53 in use, free that port (Waydroid needs it).
|
|
'';
|
|
|
|
width = lib.mkOption {
|
|
type = lib.types.int;
|
|
default = 1920;
|
|
description = "Waydroid rendering width (`persist.waydroid.width`).";
|
|
};
|
|
|
|
height = lib.mkOption {
|
|
type = lib.types.int;
|
|
default = 1080;
|
|
description = "Waydroid rendering height (`persist.waydroid.height`).";
|
|
};
|
|
|
|
multiWindows = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = false;
|
|
description = "Enable Waydroid multi-window integration.";
|
|
};
|
|
|
|
navigationMode = lib.mkOption {
|
|
type = lib.types.enum [ "3button" "gestures" ];
|
|
default = "gestures";
|
|
description = "Maps to Waydroid `navigation_mode` secure prop (3button=0, gestures=2).";
|
|
};
|
|
|
|
extraBaseProperties = lib.mkOption {
|
|
type = lib.types.attrsOf lib.types.str;
|
|
default = { };
|
|
description = ''
|
|
Extra `key = value` pairs written into `/var/lib/waydroid/waydroid_base.prop` on activation
|
|
(same mechanism as width/height). Use for upstream tweaks — e.g. NVIDIA hosts often need
|
|
`ro.hardware.gralloc=default` and `ro.hardware.egl=swiftshader`; Linux 5.18+ may need
|
|
`sys.use_memfd=true` ([NixOS Waydroid wiki](https://wiki.nixos.org/wiki/Waydroid)).
|
|
'';
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
networking.nftables.enable = lib.mkDefault true;
|
|
|
|
virtualisation.waydroid.enable = true;
|
|
|
|
system.activationScripts.waydroidProps = {
|
|
text = ''
|
|
PROP_FILE="/var/lib/waydroid/waydroid_base.prop"
|
|
|
|
if [ ! -f "$PROP_FILE" ]; then
|
|
echo "waydroid: $PROP_FILE not found yet, skipping prop sync."
|
|
echo "waydroid: run 'sudo waydroid init' once, then rebuild."
|
|
exit 0
|
|
fi
|
|
|
|
set_prop() {
|
|
key="$1"
|
|
value="$2"
|
|
|
|
if ${lib.getExe pkgs.gnugrep} -q "^''${key}=" "$PROP_FILE"; then
|
|
${pkgs.gnused}/bin/sed -i "s|^''${key}=.*|''${key}=''${value}|" "$PROP_FILE"
|
|
else
|
|
printf "%s=%s\n" "$key" "$value" >> "$PROP_FILE"
|
|
fi
|
|
}
|
|
|
|
set_prop "persist.waydroid.multi_windows" "${if cfg.multiWindows then "true" else "false"}"
|
|
set_prop "persist.waydroid.width" "${toString cfg.width}"
|
|
set_prop "persist.waydroid.height" "${toString cfg.height}"
|
|
${lib.concatStringsSep "\n" (
|
|
lib.mapAttrsToList (k: v: ''
|
|
set_prop ${lib.escapeShellArg k} ${lib.escapeShellArg v}'') cfg.extraBaseProperties
|
|
)}
|
|
'';
|
|
};
|
|
|
|
systemd.services.waydroid-navigation-mode = {
|
|
description = "Set Waydroid Android navigation mode";
|
|
wantedBy = [ "multi-user.target" ];
|
|
after = [ "waydroid-container.service" ];
|
|
wants = [ "waydroid-container.service" ];
|
|
path = [ config.virtualisation.waydroid.package ];
|
|
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
RemainAfterExit = true;
|
|
};
|
|
|
|
script = ''
|
|
set -eu
|
|
|
|
nav_mode="${if cfg.navigationMode == "gestures" then "2" else "0"}"
|
|
|
|
if ! systemctl -q is-active waydroid-container.service; then
|
|
exit 0
|
|
fi
|
|
|
|
for _ in $(seq 1 30); do
|
|
if waydroid shell settings put secure navigation_mode "$nav_mode" >/dev/null 2>&1; then
|
|
exit 0
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
echo "waydroid: warning: could not set navigation_mode=$nav_mode (container not ready?)" >&2
|
|
exit 0
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
}
|