Waydroid

Related articles
Linux Containers
This article or section needs language, wiki syntax or style improvements. See
Help:Style
for reference.
Reason:
Need to improve style. (Discuss in
Talk:Waydroid
)
Waydroid
is a container-based approach to boot a full Android system on a regular Linux system.
Prerequisites
CPU requirements
The requirements depend on the CPU architecture. You can check this
table
for more information.
You can check if you have the required CPU instructions with
cat /proc/cpuinfo
.
GPU requirements
Waydroid currently works best with Intel GPUs. They should work out of the box.
All AMD GPUs have been supported; if Waydroid does not work you might also want to try to build a new Waydroid image (which works for Radeon 680M), or try the NVIDIA instructions below.
NVIDIA GPUs do not work currently, but there are 2 workarounds.
Switch to integrated graphics card if possible
Use software rendering (see
#Software rendering
)
Wayland session manager
Waydroid only works in a
Wayland
session manager, so make sure you are in a Wayland session.
Note that even if you are in X11, many Wayland session managers support nested session (so you can run it inside your X11 session), the simplest example is
cage
.
Kernel modules
This article or section is being considered for removal.
Reason:
specific kernel modules for waydroid is no longer needed therefore rust_binder no needed to get waydroid work (Discuss in
Talk:Waydroid
)
You need to run a kernel which comes with the
rust_binder
module. It is included in the
linux
, and
linux-zen
kernels, but if you use a different
kernel
you may need to add it via DKMS or recompiling.
DKMS modules
The binder's DKMS module have to be used when the current kernel
does not
provide
rust_binder
.
Install
binder_linux-dkms
AUR
and load the
kernel module
binder_linux
with module options
devices=binder,hwbinder,vndbinder
(see
bug report
).
# modprobe binder-linux devices=binder,hwbinder,vndbinder
Optionally, you can setup
binder_linux
to be loaded at boot by creating configuration files in
/etc/modules-load.d/
and
/etc/modprobe.d/
(See
Kernel module
for more information).
/etc/modules-load.d/binder_linux.conf
# Load binder_linux at boot
binder_linux
/etc/modprobe.d/binder_linux.conf
# Options for binder_linux
options binder_linux devices=binder,hwbinder,vndbinder
You will also need to use the
Kernel parameter
ibt=off
to work around oops on kernels 5.18+. See
Segmentation fault when mounting /dev/binderfs
Building a kernel
Alternatively, you can recompile the
linux
kernel — or other kernel packages (>=5.7) — with the necessary options. Also see
Kernel#Compilation
.
When building a minimal kernel, keep the following requirements in mind:
IPv6 support. Without IPv6 networking built into your kernel, there will be no IPv4 connectivity in Waydroid.
Netlink sockets (
CONFIG_NF_CT_NETLINK=y
).
PSI (
CONFIG_PSI=y
).
Loop block devices (
CONFIG_BLK_DEV_LOOP=m
) - the
loop
module must be loaded before starting Waydroid.
When setting compilation options, you have 2 options available;
binder
and
binderfs
. Instructions for both are provided below.
Using binder
This article or section is out of date.
Reason:
There is now a kernel option enabled by default to build a Rust-based Android binder module
that Google provided due to several issues with the old module
. The option specified below builds the older C-based module but does not specify disabling the Rust module. This section needs to mention that the Rust module exists and clarify whether it is supported. (Discuss in
Talk:Waydroid
)
The modules can either be compiled into the kernel (
y
), into modules (
m
), or not at all (
n
). Also, not all combinations in the configuration are possible, and some options will require other options.
The configuration options below will compile binder as a module, while the last option specifies that there will be three devices created in the
/dev/
directory, when the binder module is loaded.
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=m
CONFIG_ANDROID_BINDERFS=n
CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder"
When building a kernel from the AUR, one can update the configuration with the following steps:
run
makepkg --nobuild
, which will download the sources, verify and extract them and run the
prepare()
function.
edit the
.config
file (with the dot in the filename), which is located at the base of the kernel directory.
at the end of the
prepare()
function was probably a command which regenerates the makefiles with information from the configuration, possibly
make olddefconfig
. Move that to the
build()
function, or execute it yourself.
run
makepkg --noextract
, which will continue from the place where
makepkg --nobuild
stopped.
Using binderfs
The binder kernel module has been known to cause issues for several users. To address these issues, binderfs was created. One has to choose between the old and the new way when compiling the kernel. With the options below, one will use binderfs instead.
With the kernel sources comes also a simple script to set configuration options. It will not do dependency checks, just like when editing the configuration by hand. When being in the same directory where the
.config
file lies, one can execute the following commands:
$ scripts/config --enable  CONFIG_ANDROID
$ scripts/config --enable  CONFIG_ANDROID_BINDER_IPC
$ scripts/config --enable  CONFIG_ANDROID_BINDERFS
$ scripts/config --set-str CONFIG_ANDROID_BINDER_DEVICES ""
When building a kernel from the AUR, it is enough to insert these lines at the right place in the
PKGBUILD
, usually in
prepare()
.
Setup binder devices
Make sure you have the latest version of Waydroid package, and Waydroid will automatically take care of this.
Installation
Install
the
waydroid
package.
Optionally, install
waydroid-image
AUR
or
waydroid-image-gapps
AUR
to provide the needed Android image through AUR. It is however recommended to let Waydroid itself handle downloading the images.
Afterwards init Waydroid, this will automatically download the latest Android image if it is not yet available.
# waydroid init
To init with GApps support:
# waydroid init -s GAPPS
Next
start/enable
the
waydroid-container.service
.
Waydroid should now work.
Usage
Make sure that
waydroid-container.service
is
started
then run:
$ waydroid session start
The Waydroid session is now active, the following are command examples to interact with it:
Launch a GUI:
$ waydroid show-full-ui
Launch a shell:
# waydroid shell
Install an application:
$ waydroid app install $path_to_apk
Get the application list:
$ waydroid app list
Run an application (Note, $package_name referes to the `packageName` attribute as shown by the list command and not to the literal name of the package as shown in the `Name` attribute):
$ waydroid app launch $package_name
Network
The network should work out of the box, if it is not, you might need to make sure
packet forwarding
is enabled in the kernel and allow the following rules through your firewall
before
running
Waydroid session start
.
Taking
ufw
as an example:
DNS traffic needs to be allowed:
# ufw allow 67
# ufw allow 53
Packet forwarding needs to be allowed:
# ufw default allow FORWARD
For
firewalld
, you can use those commands:
DNS:
# firewall-cmd --zone=trusted --add-port=67/udp
# firewall-cmd --zone=trusted --add-port=53/udp
Packet forwarding:
# firewall-cmd --zone=trusted --add-forward
Add the waydroid interface to a trusted:
# firewall-cmd --zone=trusted --add-interface=waydroid0
Note
We assume that interface
waydroid0
created by waydroid should be in the firewalld zone
trusted
automatically. If not so, please adjust those commands above or move interface
waydroid0
to
trusted
. You may also need
# firewall-cmd --runtime-to-permanent
to make your changes persist after a restart.
Tips and tricks
Enable Window integration with Desktop Window Manager
waydroid by default always runs in fullscreen.
If you want waydroid to integrate with your Desktop Environments Window Manager:
start a waydroid session with:
$ waydroid session start
set the required property:
$ waydroid prop set persist.waydroid.multi_windows true
restart the session:
$ waydroid session stop
$ waydroid session start
now apps should start in their own desktop windows.
more in the
official Docs
Software rendering
Make sure that you have already run:
# waydroid init
(see
#Installation
section for more information)
Then, add the following:
/var/lib/waydroid/waydroid.cfg
[properties]
ro.hardware.gralloc=default
ro.hardware.egl=swiftshader
Then run
# waydroid upgrade --offline
to apply configurations to actual props.
Finally, run
restart
the
waydroid-container.service
.
Setting viewport dimensions
To set the dimensions of the waydroid window use the following commands with the dimensions adjusted to your liking:
$ waydroid prop set persist.waydroid.width 576
$ waydroid prop set persist.waydroid.height 1024
Then
restart
the
waydroid-container.service
.
USB Controller Device
To enable connection with USB controller devices such as gamepads run these commands while the waydroid session is running:
$ waydroid prop set persist.waydroid.udev true
$ waydroid prop set persist.waydroid.uevent true
After running these commands restart the waydroid session.
Troubleshooting
If you run into issues, take a look at the official Issue Tracker:
Waydroid issue tracker
.
General tips
Waydroid is in rapid development so if you face issues, here is a good list of steps to do first:
Make sure your Waydroid package is up to date.
Make sure you have the latest Waydroid image by running
# waydroid upgrade
Reset Waydroid:
stop
the
waydroid-container.service
, run
# waydroid init -f
and
start
the service again.
You may also want to do little cleanup, run
# rm -rf /var/lib/waydroid /home/.waydroid
$ rm -rf ~/waydroid ~/.share/waydroid ~/.local/share/applications/*aydroid* ~/.local/share/waydroid
Tip
Removing
/home/.waydroid/
is unnecessary if you installed it after
2021-09
.
ARM Apps Incompatible
Use casualsnek's
waydroid-script-git
AUR
(
[1]
) to install a translation layer.
Due to optimizations in the translation layers, It is recommended to use libndk on AMD CPUs and libhoudini on Intel CPUs. However some apps will work on one translation layer and not another. so you may need to try both if a game does not work or gets bad performance.
Install libndk arm translation
# waydroid-extras install libndk
Install libhoudini arm translation
# waydroid-extras install libhoudini
Rotated apps are unusable
See
Issue 70
.
Click
F11
to switch the current app to windowed mode.
Failed to start Clipboard manager service
Install
python-pyclip
and its dependency for your graphical session (
xclip
for X11 or
wl-clipboard
for Wayland).
Sometimes the physical keyboard does not work
Press the left
Alt
key.
dnsmasq: failed to open pidfile /run/waydroid-lxc/dnsmasq.pid: Permission denied
An AppArmor rule is likely not set. Add the following rule:
/etc/apparmor.d/usr.sbin.dnsmasq
@{run}/waydroid-lxc/ r,
@{run}/waydroid-lxc/* rw,
Commands inside Waydroid shell outputs inaccessible or not found
On Arch based distributions there is a
"bug" that may appear while working with lxc-attach
that may cause this issue with commands inside
waydroid shell
like
adbd
or
settings
.
A possible workaround for this would be replace the
waydroid shell
command with:
# lxc-attach -P /var/lib/waydroid/lxc/ -n waydroid --clear-env
WARNING: Service manager /dev/binder has died
See
Issue 136
.
You should enable
PSI
.
Add
psi=1
to the
kernel command line
.
If enabling PSI does not fix this error, it is likely due to having ia32 emulation disabled. Try the following to enable the ia32 vdso:
# echo 1 > /proc/sys/abi/vsyscall32
Note that the Liquorix kernel
will never work with Waydroid
, as it uses certain schedulers that are incompatible with PSI.
Graphical Corruption on multi-gpu systems
Currently Waydroid needs to run on the same GPU the host compositor is running on. The two ways of fixing this is to either edit
/var/lib/waydroid/lxc/waydroid/config_nodes
to be the correct GPU or to change the GPU the compositor runs on.
A convenience script to achieve this can be found at the following address:
https://raw.githubusercontent.com/Quackdoc/waydroid-scripts/refs/heads/main/waydroid-choose-gpu.sh
No internet connection
Docker/iptables forwarding issue
When using Docker by default
iptables
is configured with
FORWARD DROP
( see
https://github.com/docker/for-linux/issues/103
for more information ), which needs to be changed to
FORWARD ACCEPT
as described as well in the official Waydroid documentation:
https://docs.waydro.id/debugging/networking-issues
In order to fix the internet connection for other LXC containers in the system ( such as Waydroid ) you can disable this behavior in your
/etc/docker/daemon.json
file, by adding the following property ( as described in
https://github.com/docker/for-linux/issues/103#issuecomment-3680138560
):
/etc/docker/daemon.json
{
    "ip-forward-no-drop": true
}
Once added remember to restart
iptables.service
and
docker.service
.
IPv6 needs to be enabled for Waydroid to work
Make sure IPv6 is enabled on your system even if you are not using it, otherwise Waydroid won't have Internet access.
https://bbs.archlinux.org/viewtopic.php?id=301559
This device isn't Play Protect certified
See:
https://docs.waydro.id/faq/google-play-certification
If you get this error you need to enter waydroid shell and retrieve the android id:
# waydroid shell
# ANDROID_RUNTIME_ROOT=/apex/com.android.runtime ANDROID_DATA=/data ANDROID_TZDATA_ROOT=/apex/com.android.tzdata ANDROID_I18N_ROOT=/apex/com.android.i18n sqlite3 /data/data/com.google.android.gsf/databases/gservices.db "select * from main where name = \"android_id\";"
Afterwards enter the id into this site:
https://www.google.com/android/uncertified
Wait a few minutes and restart waydroid.
Waydroid hangs after a while
This is likely due to the audio server dying, see
Issue 576
and
Issue 829
for details.
A workaround is to run:
# sysctl -w kernel.pid_max=65535
You can make it permanent by creating a
.conf
file in
/etc/sysctl.d/
and adding
kernel.pid_max=65535
to it.
/etc/sysctl.d/99-sysctl.conf
kernel.pid_max=65535
Application need unroot device
According to
Issue 1060
, add following can bypass the root detection:
/var/lib/waydroid/waydroid.cfg
[properties]
ro.product.brand=google
ro.product.manufacturer=Google
ro.system.build.product=redfin
ro.product.name=redfin
ro.product.device=redfin
ro.product.model=Pixel 5
ro.system.build.flavor=redfin-user
ro.build.fingerprint=google/redfin/redfin:11/RQ3A.211001.001/eng.electr.20230318.111310:user/release-keys
ro.system.build.description=redfin-user 11 RQ3A.211001.001 eng.electr.20230318.111310 release-keys
ro.bootimage.build.fingerprint=google/redfin/redfin:11/RQ3A.211001.001/eng.electr.20230318.111310:user/release-keys
ro.build.display.id=google/redfin/redfin:11/RQ3A.211001.001/eng.electr.20230318.111310:user/release-keys
ro.build.tags=release-keys
ro.build.description=redfin-user 11 RQ3A.211001.001 eng.electr.20230318.111310 release-keys
ro.vendor.build.fingerprint=google/redfin/redfin:11/RQ3A.211001.001/eng.electr.20230318.111310:user/release-keys
ro.vendor.build.id=RQ3A.211001.001
ro.vendor.build.tags=release-keys
ro.vendor.build.type=user
ro.odm.build.tags=release-keys
then use
waydroid upgrade --offline
to apply the configuration.
Waydroid "Phone is Starting" and boot animation loop on a ZFS rootfs
Make sure the
acltype
property of the zfs dataset housing
${HOME}/.local/share/waydroid
is set to
posixacl
. This can be set any time with
zfs set acltype=posixacl myZpool/targetDataset
to make waydroid work on ZFS. The default value on Linux is
acltype=off
which can lead to this scenario.
See also
Waydroid GitHub repo
Waydroid documentation
Waydroid Matrix group
Waydroid Telegram group