ci/android: add android to the ci

Add android to the ci, so we can test mesa on it.

Add debian/x86_test-android and test-android jobs.
One build the container to run tests, and the other execute the tests.

Android is executed on top of cuttlefish VM with virgl.
Mesa libs are replaced on the cuttlefish image, and deqp and deqp-runner
are used to execute tests.

Co-developed-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Signed-off-by: Helen Koike <helen.koike@collabora.com>
Reviewed-by: Sergi Blanch Torné <sergi.blanch.torne@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20019>
diff --git a/.gitlab-ci/container/debian/x86_test-android.sh b/.gitlab-ci/container/debian/x86_test-android.sh
new file mode 100644
index 0000000..c271530
--- /dev/null
+++ b/.gitlab-ci/container/debian/x86_test-android.sh
@@ -0,0 +1,99 @@
+#!/usr/bin/env bash
+# The relative paths in this file only become valid at runtime.
+# shellcheck disable=SC1091
+# shellcheck disable=SC2086 # we want word splitting
+
+set -e
+set -o xtrace
+
+export DEBIAN_FRONTEND=noninteractive
+
+# Ephemeral packages (installed for this script and removed again at the end)
+STABLE_EPHEMERAL=" \
+      ccache \
+      unzip \
+      dpkg-dev \
+      build-essential:native \
+      config-package-dev \
+      debhelper-compat \
+      cmake \
+      ninja-build \
+      "
+
+apt-get install -y --no-remove --no-install-recommends \
+      $STABLE_EPHEMERAL \
+      iproute2
+
+############### Building ...
+
+. .gitlab-ci/container/container_pre_build.sh
+
+############### Downloading NDK for native builds for the guest ...
+
+# Fetch the NDK and extract just the toolchain we want.
+ndk=$ANDROID_NDK
+curl -L --retry 4 -f --retry-all-errors --retry-delay 60 \
+  -o $ndk.zip https://dl.google.com/android/repository/$ndk-linux.zip
+unzip -d / $ndk.zip
+rm $ndk.zip
+
+############### Build dEQP runner
+
+export ANDROID_NDK_HOME=/$ndk
+. .gitlab-ci/container/build-rust.sh
+. .gitlab-ci/container/build-deqp-runner.sh
+
+rm -rf /root/.cargo
+rm -rf /root/.rustup
+
+############### Build dEQP GL
+
+DEQP_TARGET="android" \
+EXTRA_CMAKE_ARGS="-DDEQP_TARGET_TOOLCHAIN=ndk-modern -DANDROID_NDK_PATH=/$ndk -DANDROID_ABI=x86_64 -DDE_ANDROID_API=28" \
+. .gitlab-ci/container/build-deqp.sh
+
+############### Downloading Cuttlefish resources ...
+
+CUTTLEFISH_VERSION=9082637   # Chosen from https://ci.android.com/builds/branches/aosp-master/grid?
+
+mkdir /cuttlefish
+pushd /cuttlefish
+
+curl -L --retry 4 -f --retry-all-errors --retry-delay 60 \
+  -o aosp_cf_x86_64_phone-img-$CUTTLEFISH_VERSION.zip https://ci.android.com/builds/submitted/$CUTTLEFISH_VERSION/aosp_cf_x86_64_phone-userdebug/latest/raw/aosp_cf_x86_64_phone-img-$CUTTLEFISH_VERSION.zip
+unzip aosp_cf_x86_64_phone-img-$CUTTLEFISH_VERSION.zip
+rm aosp_cf_x86_64_phone-img-$CUTTLEFISH_VERSION.zip
+ls -lhS ./*
+
+curl -L --retry 4 -f --retry-all-errors --retry-delay 60 \
+  https://ci.android.com/builds/submitted/$CUTTLEFISH_VERSION/aosp_cf_x86_64_phone-userdebug/latest/raw/cvd-host_package.tar.gz | tar -xzvf-
+
+popd
+
+############### Building and installing Debian package ...
+
+git clone --depth 1 https://github.com/google/android-cuttlefish.git
+pushd android-cuttlefish
+
+pushd base
+dpkg-buildpackage -uc -us
+popd
+
+apt-get install -y ./cuttlefish-base_*.deb
+
+popd
+rm -rf android-cuttlefish
+
+addgroup --system kvm
+usermod -a -G kvm,cvdnetwork root
+
+############### Uninstall the build software
+
+rm -rf "/${ndk:?}"
+
+ccache --show-stats
+
+apt-get purge -y \
+      $STABLE_EPHEMERAL
+
+apt-get autoremove -y --purge
\ No newline at end of file
diff --git a/.gitlab-ci/container/gitlab-ci.yml b/.gitlab-ci/container/gitlab-ci.yml
index 696b6a6..7cbf423 100644
--- a/.gitlab-ci/container/gitlab-ci.yml
+++ b/.gitlab-ci/container/gitlab-ci.yml
@@ -236,6 +236,23 @@
   needs:
     - debian/x86_test-vk
 
+# Debian 11 based x86 test image for Android
+debian/x86_test-android:
+  extends: .use-debian/x86_test-base
+  variables:
+    MESA_IMAGE_TAG: &debian-x86_test-android ${DEBIAN_X86_TEST_ANDROID_TAG}
+    ANDROID_NDK: android-ndk-r25b
+
+.use-debian/x86_test-android:
+  extends:
+    - .set-image-base-tag
+  variables:
+    MESA_BASE_TAG: *debian-x86_test-base
+    MESA_IMAGE_PATH: ${DEBIAN_X86_TEST_ANDROID_IMAGE_PATH}
+    MESA_IMAGE_TAG: *debian-x86_test-android
+  needs:
+    - debian/x86_test-android
+
 # Debian 11 based ARM build image
 debian/arm_build:
   extends:
diff --git a/.gitlab-ci/cuttlefish-runner.sh b/.gitlab-ci/cuttlefish-runner.sh
new file mode 100755
index 0000000..d74579c
--- /dev/null
+++ b/.gitlab-ci/cuttlefish-runner.sh
@@ -0,0 +1,113 @@
+#!/usr/bin/env bash
+
+set -x
+
+export HOME=/cuttlefish
+export PATH=$PATH:/cuttlefish/bin
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${CI_PROJECT_DIR}/install/lib/:/cuttlefish/lib64
+export EGL_PLATFORM=surfaceless
+
+syslogd
+
+chown root.kvm /dev/kvm
+
+/etc/init.d/cuttlefish-host-resources start
+
+cd /cuttlefish
+
+launch_cvd --verbosity=DEBUG --report_anonymous_usage_stats=n --cpus=8 --memory_mb=8192 --gpu_mode=drm_virgl --daemon --enable_minimal_mode=true --guest_enforce_security=false --use_overlay=false
+sleep 1
+
+cd -
+
+adb connect vsock:3:5555
+ADB="adb -s vsock:3:5555"
+
+$ADB root
+sleep 1
+$ADB shell echo Hi from Android
+$ADB logcat dEQP:D *:S &
+
+# overlay vendor
+
+OV_TMPFS="/data/overlay-remount"
+$ADB shell mkdir -p "$OV_TMPFS"
+$ADB shell mount -t tmpfs none "$OV_TMPFS"
+
+$ADB shell mkdir -p "$OV_TMPFS/vendor-upper"
+$ADB shell mkdir -p "$OV_TMPFS/vendor-work"
+
+opts="lowerdir=/vendor,upperdir=$OV_TMPFS/vendor-upper,workdir=$OV_TMPFS/vendor-work"
+adb shell mount -t overlay -o "$opts" none /vendor
+
+$ADB shell setenforce 0
+
+# deqp
+
+$ADB push /deqp/modules/egl/deqp-egl /data/.
+$ADB push /deqp/assets/gl_cts/data/mustpass/egl/aosp_mustpass/3.2.6.x/egl-master.txt /data/.
+$ADB push /deqp-runner/deqp-runner /data/.
+
+# download mesa-x86_64-android.tar.zst
+
+MESA_ANDROID_ARTIFACT_URL=https://${PIPELINE_ARTIFACTS_BASE}/${MINIO_ARTIFACT_NAME}.tar.zst
+curl -L --retry 4 -f --retry-all-errors --retry-delay 60 -o ${MINIO_ARTIFACT_NAME}.tar.zst ${MESA_ANDROID_ARTIFACT_URL}
+tar -xvf ${MINIO_ARTIFACT_NAME}.tar.zst
+
+GPU_VERSION=virgl-gl
+$ADB push install/all-skips.txt /data/.
+$ADB push install/$GPU_VERSION-flakes.txt /data/.
+$ADB push install/deqp-android-virgl.toml /data/.
+
+# remove 32 bits libs from /vendor/lib
+
+$ADB shell rm /vendor/lib/dri/virtio_gpu_dri.so
+$ADB shell rm /vendor/lib/libglapi.so
+$ADB shell rm /vendor/lib/egl/libEGL_mesa.so
+
+$ADB shell rm /vendor/lib/egl/libEGL_angle.so
+$ADB shell rm /vendor/lib/egl/libEGL_emulation.so
+$ADB shell rm /vendor/lib/egl/libGLESv1_CM_angle.so
+$ADB shell rm /vendor/lib/egl/libGLESv1_CM_emulation.so
+$ADB shell rm /vendor/lib/egl/libGLESv2_angle.so
+$ADB shell rm /vendor/lib/egl/libGLESv2_emulation.so
+
+# replace on /vendor/lib64
+
+$ADB push install/lib/dri/virtio_gpu_dri.so /vendor/lib64/dri/virtio_gpu_dri.so
+$ADB push install/lib/libglapi.so /vendor/lib64/libglapi.so
+$ADB push install/lib/libEGL.so /vendor/lib64/egl/libEGL_mesa.so
+
+$ADB shell rm /vendor/lib64/egl/libEGL_angle.so
+$ADB shell rm /vendor/lib64/egl/libEGL_emulation.so
+$ADB shell rm /vendor/lib64/egl/libGLESv1_CM_angle.so
+$ADB shell rm /vendor/lib64/egl/libGLESv1_CM_emulation.so
+$ADB shell rm /vendor/lib64/egl/libGLESv2_angle.so
+$ADB shell rm /vendor/lib64/egl/libGLESv2_emulation.so
+
+# run tests
+
+RESULTS=/data/results
+DEQP_SUITE=/data/deqp-android-virgl.toml
+
+$ADB shell "mkdir /data/results; cd /data; strace -o /data/results/out.strace -f -s 1000 ./deqp-runner \
+    suite \
+    --suite $DEQP_SUITE \
+    --output $RESULTS \
+    --skips /data/all-skips.txt $DEQP_SKIPS \
+    --flakes /data/$GPU_VERSION-flakes.txt \
+    --testlog-to-xml /deqp/executor/testlog-to-xml \
+    --fraction-start $CI_NODE_INDEX \
+    --fraction `expr $CI_NODE_TOTAL \* ${DEQP_FRACTION:-1}` \
+    --jobs ${FDO_CI_CONCURRENT:-4} \
+    $DEQP_RUNNER_OPTIONS"
+
+EXIT_CODE=$?
+
+$ADB pull $RESULTS results
+
+cp /cuttlefish/cuttlefish/instances/cvd-1/logs/logcat results
+cp /cuttlefish/cuttlefish/instances/cvd-1/kernel.log results
+cp /cuttlefish/cuttlefish/instances/cvd-1/logs/launcher.log results
+
+exit $EXIT_CODE
\ No newline at end of file
diff --git a/.gitlab-ci/image-tags.yml b/.gitlab-ci/image-tags.yml
index 1ecfa6f..0e53149 100644
--- a/.gitlab-ci/image-tags.yml
+++ b/.gitlab-ci/image-tags.yml
@@ -3,7 +3,7 @@
    DEBIAN_BASE_TAG: "2023-01-20-kernel-6.1-439f86d0"
 
    DEBIAN_X86_BUILD_IMAGE_PATH: "debian/x86_build"
-   DEBIAN_BUILD_TAG: "2023-01-20-mold-1_10"
+   DEBIAN_BUILD_TAG: "2023-01-24-android"
 
    DEBIAN_X86_BUILD_MINGW_IMAGE_PATH: "debian/x86_build-mingw"
    DEBIAN_BUILD_MINGW_TAG: "2023-01-03-ci-libva-2.17"
@@ -13,6 +13,8 @@
    DEBIAN_X86_TEST_IMAGE_GL_PATH: "debian/x86_test-gl"
    DEBIAN_X86_TEST_IMAGE_VK_PATH: "debian/x86_test-vk"
    DEBIAN_X86_TEST_IMAGE_PATH: ${DEBIAN_X86_TEST_IMAGE_GL_PATH}
+   DEBIAN_X86_TEST_ANDROID_IMAGE_PATH: "debian/x86_test-android"
+   DEBIAN_X86_TEST_ANDROID_TAG: "2023-01-24-test-android-2"
 
    DEBIAN_X86_TEST_GL_TAG: "2023-01-23-vkvalidate"
    DEBIAN_X86_TEST_VK_TAG: "2023-01-12-cts"
diff --git a/.gitlab-ci/test/gitlab-ci.yml b/.gitlab-ci/test/gitlab-ci.yml
index bdfb115..fddb661 100644
--- a/.gitlab-ci/test/gitlab-ci.yml
+++ b/.gitlab-ci/test/gitlab-ci.yml
@@ -52,6 +52,20 @@
   needs:
     - debian/x86_test-gl
 
+.test-android:
+  extends:
+    - .test
+    - .use-debian/x86_test-android
+  variables:
+    MINIO_ARTIFACT_NAME: mesa-x86_64-android
+  needs:
+    - job: debian-testing
+      artifacts: true  # On the host we want the Linux build
+    - job: debian-android
+      artifacts: false  # The Android build will be downloaded later
+    - job: debian/x86_test-android
+      artifacts: false
+
 .vkd3d-proton-test:
   artifacts:
     when: on_failure
diff --git a/src/gallium/drivers/virgl/ci/deqp-android-virgl.toml b/src/gallium/drivers/virgl/ci/deqp-android-virgl.toml
new file mode 100644
index 0000000..ea55b2b
--- /dev/null
+++ b/src/gallium/drivers/virgl/ci/deqp-android-virgl.toml
@@ -0,0 +1,10 @@
+[[deqp]]
+deqp = "/data/deqp-egl"
+caselists = ["/data/egl-master.txt"]
+deqp_args = [
+    "--deqp-surface-width=256",
+    "--deqp-surface-height=256",
+    "--deqp-surface-type=pbuffer",
+    "--deqp-gl-config-name=rgba8888d24s8ms0",
+    "--deqp-visibility=hidden"
+]
\ No newline at end of file
diff --git a/src/gallium/drivers/virgl/ci/gitlab-ci.yml b/src/gallium/drivers/virgl/ci/gitlab-ci.yml
index 772460a..e260fb0 100644
--- a/src/gallium/drivers/virgl/ci/gitlab-ci.yml
+++ b/src/gallium/drivers/virgl/ci/gitlab-ci.yml
@@ -105,3 +105,13 @@
     PIGLIT_REPLAY_LOOP_TIMES: 150
     PIGLIT_REPLAY_EXTRA_ARGS: "--download-caching-proxy-url=${FDO_HTTP_CACHE_URI}"
   allow_failure: true
+
+android-virgl-llvmpipe:
+  extends:
+    - .test-android
+    - .virgl-rules
+  script:
+    - ./install/cuttlefish-runner.sh
+  artifacts:
+    paths:
+      - results/
\ No newline at end of file