Play Arknights In ArchLinux

Install binder

We need to install binder because Arknights depends on it to translate app messages to the Linux system.

Linux-zen is an alternative kernel available in the official Arch repos.

$$ \text{Arknights} \xrightarrow{\text{needs}} \text{Android OS} \xrightarrow{\text{needs}} \text{Binder IPC} \xrightarrow{\text{needs}} \text{Host Kernel Support} $$

We can use pacman to install it:

1
sudo pacman -S linux-zen linux-zen-headers

If you use an NVIDIA GPU, you may need extra effort to make it work. Since I use an AMD GPU, I don’t really care about that.

After installing linux-zen, if you use GRUB, you should use the instructions below to update your config before rebooting.

1
sudo grub-mkconfig -o /boot/grub/grub.cfg

If you use systemd-boot, it will update automatically, but you might need to check your loader entries in /boot/loader/entries to make sure linux-zen is selected.

You can use this command to check it:

1
uname -r

Waydroid

We use Waydroid as the Android emulator for playing Arknights.

Use pacman to download Waydroid.

Run waydroid init to download the image. If installation fails due to network issues, you can use the archlinuxcn repo to install waydroid-image.

Then run waydroid init again.

Download the waydroid script to install the Arm translation layer.

To improve translation performance, it is recommended to use libndk on AMD CPUs and libhoudini on Intel CPUs. However, some apps only support one specific translation layer, so if a game doesn’t work or has terrible performance, you might need to try both layers.

Requires a Python virtual environment.

Install libndk arm translation layer

1
sudo python3 main.py install libndk 

Install libhoudini arm translation layer

1
sudo python3 main.py install libhoudini

Only libhoudini works on my computer; libndk causes a black screen.

If installation fails, it might be due to network issues. Export the ports:

1
2
3
export http_proxy=http://127.0.0.1:7897
export https_proxy=http://127.0.0.1:7897
export all_proxy=socks5://127.0.0.1:7897

Install via proxy:

1
sudo -E venv/bin/python main.py

Check Android version:

1
waydroid prop get ro.build.version.release

Setting Waydroid Resolution

I use hyprland and haven’t found a good way to make the interface adapt to tiled window sizes automatically. I can only add a floating property to this window.

Define custom rules for waydroid:

1
windowrulev2 = size 1600 900, float, class:^(Waydroid)$

You can adjust the width, height, and DPI:

1
2
3
4
sudo waydroid prop set persist.waydroid.width 576
sudo waydroid prop set persist.waydroid.height 1024
sudo waydroid shell wm density 250
# Display looks good at 250

My advice is not to set these manually; let hyprland handle it.

Google Play

I originally wanted to set up Google Play, but there seems to be an issue on Google’s end, so I have to wait for a fix.

Discussion thread: Unable to register device in Google uncertified registration page .

BUG

Unknown Bug

This is likely due to the audio server dying … see Issue 576 and Issue 829 for details.

A workaround is to run:

1
# 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.

1
2
/etc/sysctl.d/99-sysctl.conf
kernel.pid_max=65535

Hard to comment, hard to fix.

The cause hasn’t been located yet, and it’s not fixed. My guess is it’s an audio issue.

Docker Disables IP Forwarding

waydroid couldn’t connect to the internet (ping packet loss). Initially, I suspected it was a TUN mode issue, but after troubleshooting, it still couldn’t connect.

1
2
 sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

When investigating the IP issue, I was told it might be caused by a conflict between Docker and waydroid.

Docker changes the iptables forwarding policy to DROP by default:

1
2
3
4
5
6
 sudo iptables -nvL FORWARD
[sudo] password for anfsity: 
Chain FORWARD (policy DROP 1735 packets, 177K bytes)
 pkts bytes target     prot opt in     out     source               destination         
 1735  177K DOCKER-USER  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
 1735  177K DOCKER-FORWARD  all  --  *      *       0.0.0.0/0            0.0.0.0/0  

Modify the forwarding policy:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
 sudo iptables -I FORWARD 1 -i waydroid0 -j ACCEPT
 sudo iptables -I FORWARD 1 -o waydroid0 -j ACCEPT
 sudo iptables -t nat -A POSTROUTING -s 192.168.240.0/24 -o wlan0 -j MASQUERADE
# Enable NAT
 sudo iptables -nvL FORWARD
Chain FORWARD (policy DROP 1973 packets, 212K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  *      waydroid0  0.0.0.0/0            0.0.0.0/0           
   28  1680 ACCEPT     all  --  waydroid0 *       0.0.0.0/0            0.0.0.0/0           
 1973  212K DOCKER-USER  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
 1973  212K DOCKER-FORWARD  all  --  *      *       0.0.0.0/0            0.0.0.0/0  

Fix successful:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
 sudo waydroid shell
[sudo] password for anfsity: 
:/ # ping bing.com
PING bing.com (150.171.28.10) 56(84) bytes of data.
64 bytes from 150.171.28.10: icmp_seq=1 ttl=114 time=71.9 ms
64 bytes from 150.171.28.10: icmp_seq=2 ttl=114 time=89.8 ms
^C
--- bing.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 71.993/80.922/89.851/8.929 ms

Save the rules after success:

1
2
sudo iptables-save | sudo tee /etc/iptables/iptables.rules
sudo systemctl enable --now iptables

Shortcuts

Use ydotool

1
sudo pacman -S ydotool bc

Since I have dual monitors, the hyprland pixel coordinates and ydotool pixel coordinates are different. Testing this makes me want to puke 🤮. Put on hold for now.

Other Knowledge

waydroid shell is similar to adb shell, but since it’s a container, it’s faster than ADB and has higher privileges.

waydroid file paths are stored in .local/share/waydroid/data/media/0

Access requires root privileges:

1
2
3
4
5
6
7
8
9
 ls .local/share/waydroid/data/media/0
".local/share/waydroid/data/media/0": Permission denied (os error 13)
 sudo ls .local/share/waydroid/data/media/0
[sudo] password for anfsity: 
Alarms	Audiobooks  Documents	Movies	Notifications  Podcasts    Ringtones
Android  DCIM	    Download	Music	Pictures       Recordings
 sudo ls .local/share/waydroid/data/media/0/Download
app-release.apk		clash-for-android.apk	NeteaseCloudMusic_Music_official_9.4.15.251120174454_32614.apk
clash-for-android-1.apk  netease		TapTap_2.89.0-rel.100100_rep.apk

You can install APKs via the terminal:

1
waydroid app install /path/to/your-app.apk

List installed apps:

1
waydroid app list

Debug log information:

1
2
3
4
5
waydroid logcat
# Only show errors
waydroid logcat *:E
# Use grep to filter info
waydroid logcat | grep "com.bilibili"

Besides using logcat, since the kernel is shared, you can also use dmesg to capture logs.

1
sudo dmesg -w | grep -iE "waydroid|binder|lxc"

The Android configuration file is located at /var/lib/waydroid/waydroid_base.prop.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
cat /var/lib/waydroid/waydroid_base.prop
sys.use_memfd=true
ro.adb.secure=1
ro.debuggable=0
gralloc.gbm.device=/dev/dri/renderD128
debug.stagefright.ccodec=0
ro.hardware.gralloc=gbm
ro.hardware.egl=mesa
ro.hardware.vulkan=radeon
ro.hardware.camera=v4l2
ro.opengles.version=196610
waydroid.updater.disabled=true
waydroid.tools_version=1.6.0
ro.vndk.lite=true
ro.product.cpu.abilist=x86_64,x86,arm64-v8a,armeabi-v7a,armeabi
ro.product.cpu.abilist32=x86,armeabi-v7a,armeabi
ro.product.cpu.abilist64=x86_64,arm64-v8a
ro.dalvik.vm.native.bridge=libhoudini.so
ro.enable.native.bridge.exec=1
ro.dalvik.vm.isa.arm=x86
ro.dalvik.vm.isa.arm64=x86_64

waydroid has two UI modes: Multi-Window and Full-UI.

Multi-window allows apps to become independent wayland windows.

Full-UI renders a complete Android desktop.

会长寻找灵感中...
Built with Hugo
Theme Stack designed by Jimmy
Published 3 aritcles · Total 12.79k words