Windows 11 içinde WSL Linux Sanal Makinesine Android Cihazını Bağlayarak Hata Ayıklamak
Amacım: Android telefonumdaki uygulamayı Appium ile test etmek istiyorum.
Ortamım: Windows 11 benim ev sahibi bilgisayarım (dizüstü makinenin işletim sistemi). İçinde Ubuntu 24 sanal makinesi WSL olarak çalışıyor. Docker konteyner olarak appium/appium kalıbını kullanarak bir geliştirme ortamı hazırladım.
Sorunum: Android telefonumu Win11 içinde adb devices
komutunun çıktısında görüyorum ancak Ubuntu içinde listeleyemiyorum.
Çözümüm: Win11'in WSL’e USB bağlantılarını yönlendirmesi gerekiyor ve bunu usbipd-win 4.3.0 uygulamasıyla yapmak gerekiyor. Kaynak için buraya bakabilirsiniz.
Öncelikle WSL içinde adb işlemlerini yapabilmek için WSL içindeki Ubuntu sunucunuzda android komut satırı araçlarını kurun:
sudo apt update
sudo apt install android-tools-adb
Win11 içinde en başta telefonunuz “Not Shared
” durumundadır. Ama telefonunuz “Attached
” veya “Shared
” durumlarından birinde de olabilir. Eğer telefonunuzu başlangıç durumu olan “Not Shared
” durumuna getirmek istiyorsanız usbipd unbind --busid 4–4
komutunu çalıştırabiliriz.
Eğer Win11 makinenizde adb
sunucusu çalışıyorsa kapandığından emin oluncaya kadar adb kill-server
komutunu çalıştırabilirsiniz.
D:\adb-platform-tools>adb kill-server
cannot connect to daemon at tcp:5037: cannot connect to 127.0.0.1:5037: No connection could be made because the target machine actively refused it. (10061)
NOT: Bu kısımları daha açıklayıcı olsun diye sonradan tekrar yazıyorum. Bu yüzden bus id değeri 2–3 yerine 4–4 olarak tanınan telefonu işlediğim ekran görüntülerini paylaşacağım. Aynı telefon ancak farklı bus id değeri, korkulacak bir şey yok ;)
Hem W11 hem Noble üzerinde adb sunucusu çalışmıyor
Windows 11 sisteminize yazılımı indirip kurduktan sonra usbipd list
komutuyla bağlı cihazları listeleyin:
Önce Redmine telefonu Shared durumuna (STATE) getirelim
Administrator haklarıyla tekrar cihazı Shared durumuyla bağlamaya çalışıyorum:
Telefonu WSL’e Bağlamak
Android cihazın BUSID değerini usbipd attach --wsl --busid 4-4
komutuyla WSL sunucunuza bağlıyorsunuz:
usbipd attach --wsl --busid 4-4
Win11 içinde telefonunuzun STATE bilgisi artık Attached oldu:
Telefonu Konteynere Bağlamak
Appium’un konteyner kalıplarını docker hub üzerinden bulabilirsiniz ancak kendinize özgü bir konteyner kalıbı üretecekseniz bu adresteki Dockerfile işinize yarayacaktır.
Ben scrcpy ile konteyner içinden telefonun ekranına erişebilmek için Dockerfile dosyasını güncelledim. Bazı ağ araçlarını ekledim, python ile konteynerde geliştirme yapmak için pip ekledim vs. Önce repoyu çektim sonra Dockerfile dosyasını aşağıdaki gibi güncelledim:
git clone https://github.com/appium/appium-docker-android.git
Güncelleyelim Dockerfile dosyamızı:
FROM ubuntu:noble
ENV DEBIAN_FRONTEND=noninteractive
#==================
# General Packages
#------------------
# ca-certificates
# SSL client
# curl
# Transfer data from or to a server
# gnupg
# Encryption software. It is needed for nodejs
# libgconf-2-4
# Required package for chrome and chromedriver to run on Linux
# libqt5webkit5
# Web content engine (Fix issue in Android)
# openjdk-11-jdk
# Java
# sudo
# Sudo user
# tzdata
# Timezone
# unzip
# Unzip zip file
# wget
# Network downloader
# xvfb
# X virtual framebuffer
# zip
# Make a zip file
#==================
RUN apt update && apt dist-upgrade -y
RUN apt install -y \
ca-certificates \
curl \
gnupg \
sudo \
tzdata \
unzip \
wget \
xvfb \
zip \
libqt5webkit5 \
openjdk-11-jdk \
ffmpeg
# && rm -rf /var/lib/apt/lists/*
RUN apt install -y net-tools iproute2 \
maven \
git \
# ffmpeg libsdl2-2.0-0 adb gcc pkg-config meson ninja-build libavcodec-dev libavdevice-dev libavformat-dev libavutil-dev libswresample-dev libusb-1.0-0-dev \
python3-pip
#===============
# Set JAVA_HOME
#===============
ENV JAVA_HOME="/usr/lib/jvm/java-11-openjdk-amd64" \
PATH=$PATH:$JAVA_HOME/bin
#===============================
# Set Timezone (UTC as default)
#===============================
ENV TZ "UTC"
RUN echo "${TZ}" > /etc/timezone \
&& dpkg-reconfigure --frontend noninteractive tzdata
#===============
# Create a user
#===============
ARG USER_PASS=secret
RUN groupadd androidusr \
--gid 1301 \
&& useradd androidusr \
--uid 1300 \
--gid 1301 \
--create-home \
--shell /bin/bash \
&& usermod -aG sudo androidusr \
&& echo androidusr:${USER_PASS} | chpasswd \
&& echo 'androidusr ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
WORKDIR /home/androidusr
#=====================
# Install Android SDK
#=====================
ENV SDK_VERSION=commandlinetools-linux-8512546_latest
ENV ANDROID_BUILD_TOOLS_VERSION=34.0.0
ENV ANDROID_FOLDER_NAME=cmdline-tools
ENV ANDROID_DOWNLOAD_PATH=/home/androidusr/${ANDROID_FOLDER_NAME} \
ANDROID_HOME=/opt/android \
ANDROID_TOOL_HOME=/opt/android/${ANDROID_FOLDER_NAME}
RUN wget -O tools.zip https://dl.google.com/android/repository/${SDK_VERSION}.zip && \
unzip tools.zip && rm tools.zip && \
chmod a+x -R ${ANDROID_DOWNLOAD_PATH} && \
chown -R 1300:1301 ${ANDROID_DOWNLOAD_PATH} && \
mkdir -p ${ANDROID_TOOL_HOME} && \
mv ${ANDROID_DOWNLOAD_PATH} ${ANDROID_TOOL_HOME}/tools
ENV PATH=$PATH:${ANDROID_TOOL_HOME}/tools:${ANDROID_TOOL_HOME}/tools/bin
# https://askubuntu.com/questions/885658/android-sdk-repositories-cfg-could-not-be-loaded
RUN mkdir -p ~/.android && \
touch ~/.android/repositories.cfg && \
echo y | sdkmanager "platform-tools" && \
echo y | sdkmanager "build-tools;$ANDROID_BUILD_TOOLS_VERSION" && \
mv ~/.android .android && \
chown -R 1300:1301 .android
ENV PATH=$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools
#====================================
# Install latest nodejs, npm, appium
# Using this workaround to install Appium -> https://github.com/appium/appium/issues/10020 -> Please remove this workaround asap
#====================================
ENV NODE_VERSION=18
ENV APPIUM_VERSION=2.11.4
RUN curl -sL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash \
&& apt-get -qqy install nodejs \
&& npm install -g appium@${APPIUM_VERSION} \
&& exit 0 \
&& npm cache clean
# && apt-get remove --purge -y npm \
# && apt-get autoremove --purge -y \
# && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
# && apt-get clean
#====================================================
# Fix permission issue to download e.g. chromedriver
#====================================================
RUN chown -R 1300:1301 /usr/lib/node_modules/appium
#==============
# Copy scripts
#==============
ENV SCRIPT_PATH="appium-docker-android"
RUN mkdir -p ${SCRIPT_PATH}
COPY start.sh \
generate_selenium_config.sh \
wireless_autoconnect.sh \
wireless_connect.sh \
${SCRIPT_PATH}/
RUN chown -R 1300:1301 ${SCRIPT_PATH}
ENV APP_PATH=/home/androidusr/${SCRIPT_PATH}
#==================
# Use created user
#==================
USER 1300:1301
#===============================
# Install basic Android drivers
#===============================
ENV APPIUM_DRIVER_ESPRESSO_VERSION="3.5.0"
ENV APPIUM_DRIVER_FLUTTER_VERSION="2.9.2"
ENV APPIUM_DRIVER_FLUTTER_INTEGRATION_VERSION="1.1.3"
ENV APPIUM_DRIVER_GECKO_VERSION="1.4.0"
ENV APPIUM_DRIVER_UIAUTOMATOR2_VERSION="3.8.0"
RUN appium driver install --source=npm appium-espresso-driver@${APPIUM_DRIVER_ESPRESSO_VERSION} && \
appium driver install --source=npm appium-flutter-driver@${APPIUM_DRIVER_FLUTTER_VERSION} && \
appium driver install --source=npm appium-flutter-integration-driver@${APPIUM_DRIVER_FLUTTER_INTEGRATION_VERSION} && \
appium driver install --source=npm appium-geckodriver@${APPIUM_DRIVER_GECKO_VERSION} && \
appium driver install --source=npm appium-uiautomator2-driver@${APPIUM_DRIVER_UIAUTOMATOR2_VERSION}
#===============
# Expose Port
#---------------
# 4723
# Appium port
#===============
EXPOSE 4723
#==============
# Start script
#==============
CMD ./${SCRIPT_PATH}/start.sh
Kalıp oluşturmak için:
docker build -t "appium/appium:noble" -f Appium/Dockerfile Appium
Eğer hazır appium/appium kalıbından bir konteyner kullanacaksanız önce USB aygıtını konteynere bağlayarak (-v /dev/bus/usb:/dev/bus/usb
) başlatmanız gerekiyor:
$ docker run -d \
--name ccc \
--privileged \
--rm \
-p 4723:4723 \
-v /dev/bus/usb:/dev/bus/usb \
appium/appium
-d
Anahtarıyla başlatıyorum çünkü appium kalıbının başlarken bir kabuk betiğini çalıştırması gerekiyor. -it
anahtarı verseydim en sona yazacağım komut ile bu betiği ezmiş olacaktım.
--privileged
anahtarı ile konteynerin Ubuntu host içinde erişim yetkisini root
seviyesine çekiyorum.
--rm
bayrağı ile konteyneri durdurursam otomatik silinmesini sağlıyorum
-p
anahtarı ile host içinden konteynerin appium sunucusuna isteklerin gelmesini sağlayacak port yönlendirmeyi faal hale getiriyorum.
-v /dev/bus/usb:/dev/bus/usb
ile USB aygıtına erişim sağlayan dosyayı konteynerin içine bağlıyorum ki adb
komutları bu aygıt üzerinden işleyebilsin
Unutmayın! Eğer Windows 11 makinenizde yahut Ubuntu sanal sunucunuzda
adb
’nin sunucusu çalışıyorsa konteynerdeadb devices
komutu işe yaramayacaktır. Sadeceadb
komutlarının koşmasını istediğiniz yerdeadb start-server
komutunu çalıştırmalı, diğer ortamlardaadb kill-server
komutunu koşturmalısınız.
Konteynere terminalinizi bağlayarak adb devices
komutunu çalıştırmanız yeterli olacak:
Konteyneri kapattığımda WSL artık cihazınızı görebilecek ancak telefonunuzda her bağlandığınız yeni makine için ekrana gelecek diyalog kutusuna onay vermeniz gerekiyor:
devcontainer İle Konteynerde Geliştirme Yapmak
Eğer appium geliştirmesini konteyner içinde yapmak istereseniz aşağıdaki dizin dosya yapısında ve dosya içeriklerinde bir klasör oluşturmanız yeterli olacak:
cemt@PC-CEM-TOPKAYA:~/_REPOSITORIES/_APPIUM/pressTheButton$ ll
total 20
drwxr-xr-x 5 cemt cemt 4096 Dec 6 01:48 ./
drwxr-xr-x 3 cemt cemt 4096 Dec 6 01:23 ../
drwxr-xr-x 2 cemt cemt 4096 Dec 6 01:25 .devcontainer/
drwxr-xr-x 2 cemt cemt 4096 Dec 6 02:20 java/
drwxr-xr-x 2 cemt cemt 4096 Dec 6 01:51 python/
cemt@PC-CEM-TOPKAYA:~/_REPOSITORIES/_APPIUM/pressTheButton$ tree
.
├── java
│ └── pom.xml
└── python
├── main.py
└── requirements.txt
3 directories, 3 files
devcontainer.json:
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "Appium Development",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
// "image": "appium/appium:noble"
"build": {
"dockerfile": "Dockerfile"
},
"runArgs": ["--privileged"],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [4723],
"mounts": [
"source=/dev/bus/usb,target=/dev/bus/usb,type=bind"
],
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "pip3 install --user -r ./python/requirements.txt && mvn install -f ./java/pom.xml",
"postCreateCommand": "mvn install -f ./java/pom.xml",
// Configure tool-specific properties.
"customizations": {
"vscode": {
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
"extensions": [
"ms-python.vscode-pylance",
"ms-python.pylint",
"vscjava.vscode-java-pack",
"Oracle.oracle-java",
"GitHub.copilot",
"GitHub.copilot-chat"
]
}
},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
"remoteUser": "root"
}
Ben appium/appium:noble
ismiyle ürettiğim kalıbın içinde kod geliştirmek istedim. Ama siz Dockerfile
dosyasını güncelleyerek devam edebilirsiniz.