#! /bin/bash set -e PHONE_ADB_SERIAL_NUMBER=${ADB_DEVICE} # The adb serial number can be found by running `adb devices`. if [$PHONE_ADB_SERIAL_NUMBER = '']; then PHONE_ADB_SERIAL_NUMBER=$(echo $(adb devices) | sed -rn 's/(^|(.* ))([^ ]*) device(( .*)|$)/\3/; T; p; q') fi print_message() { printf "$1\n" } check_phone_is_connected() { if ! adb devices | grep --silent "$PHONE_ADB_SERIAL_NUMBER"; then print_message "ERROR: phone '$PHONE_ADB_SERIAL_NUMBER' is not connected" adb devices -l exit 1 fi print_message "Operations will be performed on:" adb devices -l | grep $PHONE_ADB_SERIAL_NUMBER } check_phone_is_in_fastboot_mode() { fastboot devices | grep --silent "$PHONE_ADB_SERIAL_NUMBER" } get_lineage_version() { adb -s "$PHONE_ADB_SERIAL_NUMBER" shell getprop ro.lineage.version | tr -d '\n' } get_device_name() { adb -s "$PHONE_ADB_SERIAL_NUMBER" shell getprop ro.lineage.device | tr -d '\n' } get_device_downloads_page() { echo "https://download.lineageos.org/$(get_device_name)" } get_build_url() { curl --no-progress-meter "$(get_device_downloads_page)" | grep --only-matching --ignore-case \ "https://mirrorbits.lineageos.org/[^\"]*"$( )"$(get_lineage_version)-signed.zip" | head -1 } check_exists_latest_lineageos_build() { if [[ -f /tmp/lineageos.zip ]]; then # The --location lets curl follow the redirection. print_message "$(get_build_url)?sha256" curl --location "$(get_build_url)?sha256" --output /tmp/lineageos.sha256 hash1=$( awk '{print $1}' /tmp/lineageos.sha256 ) hash2=$( sha256sum /tmp/lineageos.zip | awk '{print $1}' ) [[ -n $hash1 && -n $hash2 && $hash1 == $hash2 ]] fi return } download_latest_lineageos_build() { # The --location lets curl follow the redirection. curl --location "$(get_build_url)" --output /tmp/lineageos.zip } extract_boot_image() { # See https://wiki.lineageos.org/extracting_blobs_from_zips to understand the different ways to extract the boot.img file. if is_ota_block_based; then extract_boot_image_from_block_based_ota elif is_ota_payload_based; then extract_boot_image_from_payload_based_ota else extract_boot_image_from_file_based_ota fi } extract_boot_image_from_file_based_ota() { echo 'ERROR: the function "extract_boot_image_from_file_based_ota" is not implemented' exit 1 } extract_payload_from_payload_based_ota() { unzip -od /tmp /tmp/lineageos.zip payload.bin } generate_random_alnum_string_of_length_6() { tr -dc A-Za-z0-9 60)); then echo "Giving up..." exit 2 fi echo "Phone is not in fastboot mode yet. Waiting..." sleep 5 done } flash_patched_boot_image() { fastboot -s "$PHONE_ADB_SERIAL_NUMBER" flash boot /tmp/patched-boot.img } reboot_phone() { fastboot -s "$PHONE_ADB_SERIAL_NUMBER" reboot } check_magisk_app() { magisk_package_name="com.topjohnwu.magisk" magisk_package_name_count=$(adb -s "$PHONE_ADB_SERIAL_NUMBER" shell pm list packages "$magisk_package_name" | wc -l) if [ "${magisk_package_name_count}" -eq 1 ] then print_message " [OK] Magisk app seems to be installed on selected phone" elif [ "${magisk_package_name_count}" -eq 0 ] then print_message " [ERROR] Magisk app seems not installed on selected phone. Exiting." exit -1 else print_message " [ERROR] More than one Magisk app entry is present:" adb -s "$PHONE_ADB_SERIAL_NUMBER" shell pm list packages "$magisk_package_name" print_message "Exiting." exit -1 fi } is_rooted_debugging_enabled() { adb -s "$PHONE_ADB_SERIAL_NUMBER" root } main() { print_message "Looking for phone '$PHONE_ADB_SERIAL_NUMBER'" check_phone_is_connected print_message "Checking on phone if rooted debugging is enabled" is_rooted_debugging_enabled print_message "Checking on phone if Magisk is installed" check_magisk_app print_message "Checking if build archive already exists" if check_exists_latest_lineageos_build; then print_message "Build archive found, skipping download" else print_message "Build archive not found or hash mismatch, downloading from $(get_build_url)" download_latest_lineageos_build fi print_message "Extracting 'boot.img' from build archive in /tmp/boot.img" extract_boot_image print_message "Copying from PC to phone the boot image in /sdcard/Download/boot.img" transfer_unpatched_boot_image_to_phone print_message "Patching boot image with Magisk script and moving it in /sdcard/Download/patched-boot.img" patch_boot_image_on_phone print_message "Copying patched boot image from phone to PC in /tmp/patched-boot.img" transfer_patched_boot_image_to_pc print_message "Rebooting phone in fastboot mode" reboot_to_bootloader wait_for_phone_to_be_in_fastboot print_message "Flashing patched boot image on phone" flash_patched_boot_image print_message "Rebooting phone" reboot_phone } # Run the main only when this file is executed as script, to help with testing. if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then main "$@" fi