diff --git a/.DS_Store b/.DS_Store index 3dc6b3a..8168bca 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/mac/.DS_Store b/mac/.DS_Store index 3ea1f6d..7626e09 100644 Binary files a/mac/.DS_Store and b/mac/.DS_Store differ diff --git a/unix/.DS_Store b/unix/.DS_Store index 3ea1f6d..3bbf10b 100644 Binary files a/unix/.DS_Store and b/unix/.DS_Store differ diff --git a/unix/docker/images/android/Dockerfile b/unix/docker/images/android/Dockerfile index d2491d9..1c07cc6 100644 --- a/unix/docker/images/android/Dockerfile +++ b/unix/docker/images/android/Dockerfile @@ -7,6 +7,8 @@ ARG JAVA_IMAGE=java-17 FROM ${JAVA_IMAGE} +RUN echo ${JAVA_IMAGE} + ENV ANDROID_SDK_ROOT="/usr/local/android-sdk" ENV PATH=$PATH:$ANDROID_SDK_ROOT/cmdline-tools/latest:$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$ANDROID_SDK_ROOT/platform-tools @@ -25,13 +27,15 @@ RUN yes | sdkmanager --licenses RUN echo y | sdkmanager "tools" && \ echo y | sdkmanager "platform-tools" && \ + echo y | sdkmanager "build-tools;35.0.0" && \ echo y | sdkmanager "build-tools;34.0.0" && \ echo y | sdkmanager "build-tools;33.0.2" && \ echo y | sdkmanager "build-tools;33.0.1" && \ echo y | sdkmanager "build-tools;32.1.0-rc1" && \ echo y | sdkmanager "build-tools;30.0.3" -RUN echo y | sdkmanager "platforms;android-34" && \ +RUN echo y | sdkmanager "platforms;android-35" && \ + echo y | sdkmanager "platforms;android-34" && \ echo y | sdkmanager "platforms;android-33" && \ echo y | sdkmanager "platforms;android-32" && \ echo y | sdkmanager "platforms;android-31" diff --git a/unix/docker/images/android/emulator-maestro/Dockerfile b/unix/docker/images/android/emulator-maestro/Dockerfile new file mode 100644 index 0000000..ae46cad --- /dev/null +++ b/unix/docker/images/android/emulator-maestro/Dockerfile @@ -0,0 +1,86 @@ +# Example build commands: +# $ docker build -t j17-android-emulator . +# $ docker build --build-arg ANDROID_IMAGE=j17-android -t j17-android-emulator . + +# Example run commands: +# $ docker run -it -d -p 5900:5900 --name androidContainer -e VNC_PASSWORD=123 --privileged j17-android-emulator +# $ docker exec --privileged -it androidContainer bash -c "./start_vnc.sh" + +# Java 21 Android image is default +ARG ANDROID_IMAGE=j21-android + +FROM ${ANDROID_IMAGE} + +# Avoid being asked interactive questions when installing packages +ARG DEBIAN_FRONTEND=noninteractive + +# Install packages +RUN apt-get update && apt-get install -y \ + bzip2 \ + libdrm-dev \ + libxkbcommon-dev \ + libgbm-dev \ + libasound-dev \ + libnss3 \ + libxcursor1 \ + libpulse-dev \ + libxshmfence-dev \ + xauth \ + xvfb \ + x11vnc \ + fluxbox \ + wmctrl \ + python3 \ + python3-pip \ + libdbus-glib-1-2 && \ + rm -rf /var/lib/apt/lists/* + +# Define emulator parameters +ARG ARCH=x86_64 \ + TARGET=google_apis_playstore \ + EMULATOR_API_LEVEL=34 \ + EMULATOR_NAME="Pixel_7_Pro" \ + EMULATOR_DEVICE="pixel_7_pro" + +ENV EMULATOR_PACKAGE=system-images;android-${EMULATOR_API_LEVEL};${TARGET};${ARCH} \ + EMULATOR_NAME=$EMULATOR_NAME \ + EMULATOR_DEVICE=$EMULATOR_DEVICE \ + ANDROID_AVD_HOME="/root/.android/avd" + +# Install emulator tools +RUN sdkmanager "${EMULATOR_PACKAGE}" "emulator" + +# List possible devices +RUN avdmanager list device + +# Create required emulator AVD +RUN echo "no" | avdmanager create avd --force --name "${EMULATOR_NAME}" --device "${EMULATOR_DEVICE}" --package "${EMULATOR_PACKAGE}" + +COPY . / + +# Add permissions for emulator launch scripts ans VNC start script +RUN chmod a+x /emu_scripts/start_emu_headless.sh && \ + chmod a+x /emu_scripts/start_emu.sh && \ + chmod a+x /emu_scripts/start_vnc.sh + +# Add script and emulator to the PATH +ENV PATH=$PATH:/emu_scripts:$ANDROID_SDK_ROOT/emulator + +# Install pip +RUN pip3 install virtualenv + +# Install Maestro +ENV MAESTRO_VERSION 1.41.0 + +RUN mkdir -p /opt/maestro && \ +wget -q -O /tmp/${MAESTRO_VERSION} "https://github.com/mobile-dev-inc/maestro/releases/download/cli-${MAESTRO_VERSION}/maestro.zip" && \ +unzip -q /tmp/${MAESTRO_VERSION} -d /opt/ && \ +rm /tmp/${MAESTRO_VERSION} +ENV PATH=/opt/maestro/bin:${PATH} + +# Install fonts for Maestro recording +RUN apt-get update && apt-get install -y \ + fonts-noto \ + fonts-noto-mono \ + fonts-noto-color-emoji && fc-cache -f -v + diff --git a/unix/docker/images/android/emulator-maestro/emu_scripts/start_emu.sh b/unix/docker/images/android/emulator-maestro/emu_scripts/start_emu.sh new file mode 100644 index 0000000..d12e97a --- /dev/null +++ b/unix/docker/images/android/emulator-maestro/emu_scripts/start_emu.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +BL='\033[0;34m' +G='\033[0;32m' +RED='\033[0;31m' +YE='\033[1;33m' +NC='\033[0m' # No Color + + +emulator_name=${EMULATOR_NAME} + +function launch_emulator() { + adb devices | grep emulator | cut -f1 | xargs -I {} adb -s "{}" emu kill + options="@${emulator_name} -no-boot-anim" + + if [[ "$OSTYPE" == *linux* ]]; then + echo "${OSTYPE}: emulator ${options} -gpu off" + nohup emulator $options -gpu off & + fi + if [[ "$OSTYPE" == *darwin* ]] || [[ "$OSTYPE" == *macos* ]]; then + echo "${OSTYPE}: emulator ${options} -gpu swiftshader_indirect" + nohup emulator $options -gpu swiftshader_indirect & + fi + + if [ $? -ne 0 ]; then + echo "Error launching emulator" + return 1 + fi +} + +function check_emulator_status () { + printf "${G}==> ${BL}Checking emulator booting up status 🧐${NC}\n" + start_time=$(date +%s) + spinner=( "⠹" "⠺" "⠼" "⠶" "⠦" "⠧" "⠇" "⠏" ) + i=0 + # Get the timeout value from the environment variable or use the default value of 300 seconds (5 minutes) + timeout=${EMULATOR_TIMEOUT:-300} + + while true; do + result=$(adb shell getprop sys.boot_completed 2>&1) + + if [ "$result" == "1" ]; then + printf "\e[K${G}==> \u2713 Emulator is ready : '$result' ${NC}\n" + adb devices -l + adb shell input keyevent 82 + break + elif [ "$result" == "" ]; then + printf "${YE}==> Emulator is partially Booted! 😕 ${spinner[$i]} ${NC}\r" + else + printf "${RED}==> $result, please wait ${spinner[$i]} ${NC}\r" + i=$(( (i+1) % 8 )) + fi + + current_time=$(date +%s) + elapsed_time=$((current_time - start_time)) + if [ $elapsed_time -gt $timeout ]; then + printf "${RED}==> Timeout after ${timeout} seconds elapsed 🕛.. ${NC}\n" + break + fi + sleep 4 + done +}; + +function disable_animation() { + adb shell "settings put global window_animation_scale 0.0" + adb shell "settings put global transition_animation_scale 0.0" + adb shell "settings put global animator_duration_scale 0.0" +} + +launch_emulator +sleep 2 +check_emulator_status +sleep 1 +disable_animation diff --git a/unix/docker/images/android/emulator-maestro/emu_scripts/start_emu_headless.sh b/unix/docker/images/android/emulator-maestro/emu_scripts/start_emu_headless.sh new file mode 100644 index 0000000..f54ee9a --- /dev/null +++ b/unix/docker/images/android/emulator-maestro/emu_scripts/start_emu_headless.sh @@ -0,0 +1,108 @@ +#!/bin/bash + +BL='\033[0;34m' +G='\033[0;32m' +RED='\033[0;31m' +YE='\033[1;33m' +NC='\033[0m' # No Color + + +emulator_name=${EMULATOR_NAME} + +function check_hardware_acceleration() { + if [[ "$HW_ACCEL_OVERRIDE" != "" ]]; then + hw_accel_flag="$HW_ACCEL_OVERRIDE" + else + if [[ "$OSTYPE" == "darwin"* ]]; then + # macOS-specific hardware acceleration check + HW_ACCEL_SUPPORT=$(sysctl -a | grep -E -c '(vmx|svm)') + else + # generic Linux hardware acceleration check + HW_ACCEL_SUPPORT=$(grep -E -c '(vmx|svm)' /proc/cpuinfo) + fi + + if [[ $HW_ACCEL_SUPPORT == 0 ]]; then + hw_accel_flag="-accel off" + else + hw_accel_flag="-accel on" + fi + fi + + echo "$hw_accel_flag" +} + +# NOT IN USE ATM. +hw_accel_flag=$(check_hardware_acceleration) + +function launch_emulator () { + adb devices | grep emulator | cut -f1 | xargs -I {} adb -s "{}" emu kill + options="@${emulator_name} -no-window -no-boot-anim" + + if [[ "$OSTYPE" == *linux* ]]; then + echo "${OSTYPE}: emulator ${options} -gpu off" + nohup emulator $options -gpu off & + fi + if [[ "$OSTYPE" == *darwin* ]] || [[ "$OSTYPE" == *macos* ]]; then + echo "${OSTYPE}: emulator ${options} -gpu swiftshader_indirect" + nohup emulator $options -gpu swiftshader_indirect & + fi + + if [ $? -ne 0 ]; then + echo "Error launching emulator" + return 1 + fi +} + +function check_emulator_status () { + printf "${G}==> ${BL}Checking emulator booting up status 🧐${NC}\n" + start_time=$(date +%s) + spinner=( "⠹" "⠺" "⠼" "⠶" "⠦" "⠧" "⠇" "⠏" ) + i=0 + # Get the timeout value from the environment variable or use the default value of 300 seconds (5 minutes) + timeout=${EMULATOR_TIMEOUT:-300} + + while true; do + result=$(adb shell getprop sys.boot_completed 2>&1) + + if [ "$result" == "1" ]; then + printf "\e[K${G}==> \u2713 Emulator is ready : '$result' ${NC}\n" + adb devices -l + adb shell input keyevent 82 + break + elif [ "$result" == "" ]; then + printf "${YE}==> Emulator is partially Booted! 😕 ${spinner[$i]} ${NC}\r" + else + printf "${RED}==> $result, please wait ${spinner[$i]} ${NC}\r" + i=$(( (i+1) % 8 )) + fi + + current_time=$(date +%s) + elapsed_time=$((current_time - start_time)) + if [ $elapsed_time -gt $timeout ]; then + printf "${RED}==> Timeout after ${timeout} seconds elapsed 🕛.. ${NC}\n" + break + fi + sleep 4 + done +}; + +function disable_animation() { + adb shell "settings put global window_animation_scale 0.0" + adb shell "settings put global transition_animation_scale 0.0" + adb shell "settings put global animator_duration_scale 0.0" +}; + +function hidden_policy() { + adb shell "settings put global hidden_api_policy_pre_p_apps 1;settings put global hidden_api_policy_p_apps 1;settings put global hidden_api_policy 1" +}; + + +launch_emulator +sleep 2 +check_emulator_status +sleep 1 +disable_animation +sleep 1 +hidden_policy +sleep 1 + diff --git a/unix/docker/images/android/emulator-maestro/emu_scripts/start_vnc.sh b/unix/docker/images/android/emulator-maestro/emu_scripts/start_vnc.sh new file mode 100644 index 0000000..53920a6 --- /dev/null +++ b/unix/docker/images/android/emulator-maestro/emu_scripts/start_vnc.sh @@ -0,0 +1,88 @@ +#!/bin/bash + +readonly G_LOG_I='[INFO]' +readonly G_LOG_W='[WARN]' +readonly G_LOG_E='[ERROR]' +BL='\033[0;34m' +G='\033[0;32m' +NC='\033[0m' # No Color + +main() { + launch_xvfb + launch_window_manager + run_vnc_server + printf "${G}==> ${BL}Welcome to android-emulator VNC by amrsa ${G}<==${NC}""\n" +} + +launch_xvfb() { + # Set defaults if the user did not specify envs. + export DISPLAY=${XVFB_DISPLAY:-:1} + local screen=${XVFB_SCREEN:-0} + local resolution=${XVFB_RESOLUTION:-1280x1024x24} + local timeout=${XVFB_TIMEOUT:-5} + + # Start and wait for either Xvfb to be fully up or we hit the timeout. + Xvfb ${DISPLAY} -screen ${screen} ${resolution} & + local loopCount=0 + until xdpyinfo -display ${DISPLAY} > /dev/null 2>&1 + do + loopCount=$((loopCount+1)) + sleep 1 + if [ ${loopCount} -gt ${timeout} ] + then + echo "${G_LOG_E} xvfb failed to start." + exit 1 + fi + done +} + +launch_window_manager() { + local timeout=${XVFB_TIMEOUT:-5} + + # Start and wait for either fluxbox to be fully up or we hit the timeout. + fluxbox & + local loopCount=0 + until wmctrl -m > /dev/null 2>&1 + do + loopCount=$((loopCount+1)) + sleep 1 + if [ ${loopCount} -gt ${timeout} ] + then + echo "${G_LOG_E} fluxbox failed to start." + exit 1 + fi + done +} + +run_vnc_server() { + local passwordArgument='-nopw' + + if [ -n "${VNC_PASSWORD}" ] + then + local passwordFilePath="${HOME}/x11vnc.pass" + if ! x11vnc -storepasswd "${VNC_PASSWORD}" "${passwordFilePath}" + then + echo "${G_LOG_E} Failed to store x11vnc password." + exit 1 + fi + passwordArgument=-"-rfbauth ${passwordFilePath}" + echo "${G_LOG_I} The VNC server will ask for a password." + else + echo "${G_LOG_W} The VNC server will NOT ask for a password." + fi + + x11vnc -ncache_cr -display ${DISPLAY} -forever ${passwordArgument} & + wait $! +} + + +control_c() { + echo "" + exit +} + +trap control_c SIGINT SIGTERM SIGHUP + +main + +exit diff --git a/unix/docker/images/gradle+kotlin/Dockerfile b/unix/docker/images/gradle+kotlin/Dockerfile index 415905c..f577b1c 100644 --- a/unix/docker/images/gradle+kotlin/Dockerfile +++ b/unix/docker/images/gradle+kotlin/Dockerfile @@ -7,10 +7,10 @@ ARG ANDROID_IMAGE=j17-android FROM ${ANDROID_IMAGE} -ENV KOTLIN_VERSION 1.9.21 -ENV KOTLIN_COMPILER kotlin-native-prebuilt-linux-x86_64-${KOTLIN_VERSION} +ENV KOTLIN_VERSION 2.2.0 +ENV KOTLIN_COMPILER kotlin-native-prebuilt-${KOTLIN_VERSION}-linux-x86_64 -RUN wget "https://download.jetbrains.com/kotlin/native/builds/releases/${KOTLIN_VERSION}/linux-x86_64/${KOTLIN_COMPILER}.tar.gz" -q --show-progress --progress=bar:force 2>&1 &&\ +RUN wget "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-native-prebuilt/${KOTLIN_VERSION}/${KOTLIN_COMPILER}.tar.gz" -q --show-progress --progress=bar:force 2>&1 &&\ mkdir -p /root/.konan/${KOTLIN_COMPILER} &&\ tar -xzvf ${KOTLIN_COMPILER}.tar.gz -C /root/.konan &&\ rm ${KOTLIN_COMPILER}.tar.gz diff --git a/unix/docker/images/gradle+kotlin/gradle/wrapper/gradle-wrapper.properties b/unix/docker/images/gradle+kotlin/gradle/wrapper/gradle-wrapper.properties index d098017..3830a37 100644 --- a/unix/docker/images/gradle+kotlin/gradle/wrapper/gradle-wrapper.properties +++ b/unix/docker/images/gradle+kotlin/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Thu Aug 03 16:33:50 CEST 2023 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/unix/docker/images/gradle+kotlin/gradlew b/unix/docker/images/gradle+kotlin/gradlew old mode 100644 new mode 100755 diff --git a/unix/docker/images/java/Dockerfile b/unix/docker/images/java/Dockerfile index 1583c99..1e08004 100644 --- a/unix/docker/images/java/Dockerfile +++ b/unix/docker/images/java/Dockerfile @@ -7,6 +7,8 @@ FROM base-tools # Java 17 is default ARG VERSION=17 +RUN echo ${VERSION} + # Install java ${VERSION} RUN apt-get update && apt-get install -y \ openjdk-${VERSION}-jdk