快轉到主要內容

將Linux Surface平板變成Android平板 (Waydroid only session)

· 民國115年丙午年
·
切換正體/简体 ·
分類 智慧型手機 真Linux手機
標籤 Waydroid Wayland Microsoft Surface
目錄

Configuring Waydroid only session with Sway on Linux. Turning a Linux tablet into a semi-Android tablet.

我將Surface Go 2變成Android平板了,我可以在開機後選擇要進入Linux電腦版桌面,亦或是Android。這樣能大幅節省系統資源消耗。

嚴格來說,我並沒有裝真正的Android-x86 (BlissOS),這也不是ChromeOS。而是跑在Arch Linux上的Waydroid容器,透過極小的Wayland合成器讓它全螢幕執行。Linux host除了必要的SSH daemon之外,將整台主機的資源留給Android container。這就變成了Linux + Android混合平板。

具體演示影片:

原因是Linux桌面普遍並不適合觸控使用,所以我想設計一個能自由切換到Linux和Android,又不用搞雙系統的方法,成果就是這個。

Waydroid會將Android APP的畫面繪製在Linux桌面的Wayland合成器上。那麼其實就可以在Linux安裝Waydroid,並透過顯示管理器進入Android系統。簡言之,在Linux電腦開機登入之後自動進入Waydroid,好似在操作Android-x86系統一樣的感覺。這樣的話,就能把Linux平板「暫時」當作Android平板使用吧!抑或是,把裝有Ubuntu Touch或postmarketOS的PinePhone暫時變成Android手機。

我為了將裝有Surface Go 2的Linux平板變成 偽.Android平板,所以嘗試了這個作法。

1. 預期結果
#

Linux啓動的所有桌面環境都叫做一個session。開機之後第一個見到的畫面是Display Manager,譬如GDM。這裡能夠選取要啓動哪個桌面。那麼我們就能在這裡定義啓動Sway與Waydroid的行爲。自訂一個能夠啟動桌面環境工作階段的Desktop Entry,執行Wayland合成器然後馬上載入Waydroid。

Waydroid官方文件稱這種操作叫做"Waydroid only session" 不推薦使用Waydroid only session卻沒有搭配桌面環境。

因為Waydroid不是完整Android系統,容器內部無法控制外部Linux系統的音量、亮度、螢幕方向,也無法自主關機,甚至沒辦法鎖定螢幕。如果需要讓Waydroid儘可能全螢幕,又不要讓桌面環境佔用太多資源,推薦搭配輕量的Wayland合成器使用。他們允許你自由組裝出現在桌面上的元件。這樣的話會比較好控制Waydroid的行為。Waydroid官方文件提到GNOME Mutter、Weston、Wayfire、Cage的作法。我覺得Kwin應該也行吧?但我們這邊的目的是儘量簡單,只要啟動Android就好,不要其他元件。

我試過Cage,據說是爲了Kiosk mode打造的,但它功能太單一,甚至不支援wlroots的工具調整。想來想去還是我自己寫一個Sway的config,定義桌面載入後要啓動的東西吧。Sway比較主流,能用的wlroots指令工具比較多。

Linux開機後啓動GDM,我可以在這個畫面觸控,選擇要進入Linux電腦版的GNOME桌面,亦或是啓動Waydroid。

這個Waydroid的按鈕背後是一個Desktop Entry,內含Sway的啓動指令,我寫了一個最小的Sway config,綁定硬體按鍵,在登入session之後不啓動任何Linux的GUI,直接全螢幕啓動Waydroid。

爲什麼不直接在現有Linux桌面開啓Waydroid呢,因爲我想儘可能減少CPU資源佔用(GNOME隨便就2GB RAM,而Sway不到500MB),我的Surface Go 2只有4G/64G,有額外插SD卡。並且要讓Waydroid能真正全螢幕,沒有其他元素干擾。

只要Vulkan有起來,在Android看Youtube影片是沒問題的。

Surface Pen可以在Waydroid裡使用。

在啓動Waydroid之後,就只看得到Android的畫面。理論上我是可以給Sway綁定其他鍵來喚醒其他程式,但是我設想是我要沒接鍵盤也能用,要用觸控爲主。因此大部分操作應該在Android的GUI完成。

目前可以按電源鍵關閉螢幕省電,因爲我用Sway的config覆寫了logind的預設行爲,按下後會觸發DPMS off指令而非suspend。

但是不能從Android端關機。螢幕無法自動旋轉,要在Android裝調整APP強制轉向。無法調整螢幕亮度。在Android看不到實際Linux平板的電量。針對以上問題,解決方法是從從Android的Termux反向ssh回Linux host來操作。用Avahi提供的mDNS來連線就能確保連線位址不變。然後,Sway提供了swaymsg這個指令來操控硬體數值,可以調整亮度、音量。並用upower讀取電池。

那麼Waydroid能否正常休眠呢?Surface是可以進入suspend模式,但Linux的休眠跟Android差很多,這是將系統暫存到RAM然後關閉電力,是根本收不到通知的,所以我傾向讓螢幕關閉就可以了。這樣SSH不至於中斷。

Android比Linux更省電的,關閉螢幕,從SSH遠端監控發現,upowert回報的續航力高達24小時。當然螢幕一打開就瞬間掉回5小時了…..。

2. 安裝Waydroid
#

建議在現有桌面環境操作。

參考:Linux跑Android APP,Waydroid安裝教學

裝好後確認Waydroid開機後服務會自動啟動

sudo systemctl enable waydroid-container

3. 設定開機自動連線Wifi與藍牙
#

因爲進入Waydroid後無法用GUI與Linux互動,除非你有鍵盤,否則必須設定開機自動連上網路。這樣的話也方便遠端SSH進去操控系統。

  1. NetworkManager可以用nmcli設定目前的開機自動連線
sudo systemctl enable NetworkManager

nmcli

nmcli device set "連線名稱" autoconnect yes
  1. 藍牙用bluetoothd設定
sudo systemctl enable bluetooth
  1. 可以設定Avahi的mDNS服務,這樣Linux會在區域網路廣播自己,然後就能用hostname而非IP去連線
sudo systemctl enable avahi-daemon

4. 新增Sway的config
#

  1. 安裝Sway
sudo pacman -S sway
  1. 新增專門的sway config(或者留空)
mkdir -p ~/.config/sway

cp /etc/sway/config  ~/.config/sway/sway-config-waydroid

vim ~/.config/sway/sway-config-waydroid
  1. 在Sway預設的config加入以下內容,針對Waydroid設定視窗規則,還有按鍵綁定。
# 包含預設的Sway設定
include /etc/sway/config.d/*

# 移除所有視窗邊框與裝飾
default_border none
default_floating_border none

# 隱藏Sway狀態列
bar {
    mode invisible
}

# 當Waydroid視窗開啓時,自動將其設為全螢幕
for_window [app_id="waydroid"] fullscreen enable

# 啟動 Waydroid,並在 Waydroid 關閉時自動退出 Sway (使用 exec_always)
exec_always waydroid show-full-ui && swaymsg exit

# 關閉螢幕要控制DPMS,Sway有swaymsg來關閉。把它綁定給電源鍵盤,用jq判斷狀態決定要關閉螢幕還是喚醒螢幕
bindsym --locked XF86PowerOff exec swaymsg -t get_outputs | jq -e '.[] | select(.active) | .dpms' | grep -q true && swaymsg "output * dpms off" || swaymsg "output * dpms on"

5. Linux端小微調
#

  1. Surface的電源鍵無法正確關閉螢幕,systemd-logind預設會讓它關機。我用wev取得key id之後(應該是XF86PowerOff)綁定給Sway,執行開關螢幕指令。不能讓Linux休眠(suspend)否則SSH就斷掉了。

  2. 阻止systemd-logind處理硬體事件,否則按下後會關機,編輯:

sudo vim /etc/systemd/logind.conf
  1. 設定不要處理硬體事件
HandlePowerKey=ignore
  1. Sway有swayidle能自動在一段時間後關閉Linux的螢幕。不過我沒有設定。

  2. Waydroid的通知現在會轉交給桌面環境的notify deamon,我覺得很不好,都全螢幕了應該在Android畫面顯示就好。所以必須把swaync和桌面環境的notify daemon關掉,並且禁止Systemd透過D-Bus喚醒它

systemctl --user list-units | grep -i notify

systemctl --user stop <通知服務>.service

systemctl --user mask <通知服務>.service

systemctl --user daemon-reload

6. 新增Desktop Entry
#

  1. 新增一個Desktop Entry,它會出現在顯示管理器的選單
sudo vim /usr/share/wayland-sessions/sway-waydroid.desktop
  1. 填入以下內容:
[Desktop Entry]
Name=Waydroid in Sway
Comment=Android OS in a container
Exec=/usr/bin/sway -c /home/user/.config/sway/sway-config-waydroid
Type=Application
  1. 重開機。在顯示管理器的畫面點選Waydroid的按鈕啟動。

7. 操作方法
#

  1. 在啓動Waydroid之後,就只看得到Android的畫面。

  2. 安裝Termux,反向從Android用ssh連線回Linux。用nmcli把DHCP設定固定IP的話就不會變。或者Avahi daemon開啓的話就用mDNS的hostname連。

  3. Sway提供swaymsg的一系列指令來操控硬體。如果是SSH遠端執行,需要加入以下語法開頭:

swaymsg -s $(ls /run/user/$(id -u)/sway-ipc.*.sock | head -n 1) 
  1. 其他控制工具:

# wpctl控制音量
wpctl set-volume @DEFAULT_AUDIO_SINK@ 1.0

# brightnessctl遠端控制亮度
sudo brightnessctl set 500

# 取得實際電量
power -i /org/freedesktop/UPower/devices/battery_BAT1 | grep -E "state|percentage|time to empty"

# nmcli控制網路

# bluetoothd控制藍牙

相關文章


感謝您的閱讀。我寫作是為了誠實表達想法,而不是追逐社群互動與流量。我很樂意傾聽你在仔細閱讀我文章之後的心得。若有內容勘誤 or 技術問題 or 回饋想法,歡迎透過本站「關於」頁面的Email與我聯絡。