|
| 1 | +"""Script to flash a sony xperia z. |
| 2 | +
|
| 3 | +Example usage: |
| 4 | + poetry run python scripts/lineageos-on-sony-xperia-z.py --recovery images/sony-xperia-z/twrp-3.6.2_9-0-yuga.img --image images/sony-xperia-z/lineage-18.1-20220214-UNOFFICIAL-yuga.zip |
| 5 | +""" |
| 6 | +import click |
| 7 | +from subprocess import call |
| 8 | + |
| 9 | +from utils import run_fastboot_command |
| 10 | + |
| 11 | + |
| 12 | +@click.command() |
| 13 | +@click.option('--recovery', help='Path to the recovery file to flash. (Can be TWRP)') |
| 14 | +@click.option('--image', help='Path to the lineage os image to flash.') |
| 15 | +def install_lineage_os(recovery: str, image: str): |
| 16 | + # Steps 1: Unlock the bootloader |
| 17 | + unlock_result = unlocking_bootloader_result = unlock_bootloader() |
| 18 | + if not unlock_result: |
| 19 | + click.echo("Unlocking the bootloader failed. Exiting.") |
| 20 | + return False |
| 21 | + |
| 22 | + # Step 2: Temporarily booting a custom recovery using fastboot |
| 23 | + boot_recovery_result = boot_recovery(recovery) |
| 24 | + if not boot_recovery_result: |
| 25 | + click.echo("Flashing recovery failed. Exiting.") |
| 26 | + return False |
| 27 | + |
| 28 | + # Step 3: Installing LineageOS from recovery |
| 29 | + install_result = install_os(image) |
| 30 | + if not install_result: |
| 31 | + click.echo("Installing LineageOS failed. Exiting.") |
| 32 | + return False |
| 33 | + |
| 34 | + click.echo( |
| 35 | + "Installing lineageOS was successful! Have fun with your device! :)") |
| 36 | + return True |
| 37 | + |
| 38 | + |
| 39 | +def install_os(image: str): |
| 40 | + """Installing LineageOS from recovery with the image filepath given in image.""" |
| 41 | + # reboot into fastboot mode |
| 42 | + reboot_res = reboot_device_into_bootloader() |
| 43 | + if reboot_res == 4: |
| 44 | + click.echo("Booting into bootloader failed. Exiting.") |
| 45 | + return False |
| 46 | + # needs screen interaction here |
| 47 | + confirmed = click.confirm("Select 'Boot into Recovery' on your smartphone screen. Wait until you are in recovery, then confirm", |
| 48 | + default=True, abort=False, prompt_suffix=': ', show_default=True, err=False) |
| 49 | + |
| 50 | + # automatic factory reset |
| 51 | + #factory_reset_result = run_fastboot_command(cmd=["erase", "cache"]) |
| 52 | + #click.echo(f"{factory_reset_result}") |
| 53 | + #factory_reset_result = run_fastboot_command(cmd=["erase", "userdata"]) |
| 54 | + #click.echo(f"{factory_reset_result}") |
| 55 | + |
| 56 | + # manual factory reset |
| 57 | + confirmed = click.confirm( |
| 58 | + "Now tap Factory Reset, then Format data / factory reset and continue with the formatting process. This will remove encryption and delete all files stored in the internal storage, as well as format your cache partition (if you have one). Confirm if you are done", |
| 59 | + default=True, abort=False, prompt_suffix=': ', show_default=True, err=False |
| 60 | + ) |
| 61 | + |
| 62 | + # sideload linageos image with adb |
| 63 | + confirmed = click.confirm( |
| 64 | + "On the device, select “Apply Update”, then “Apply from ADB” to begin sideload. Then confirm here", |
| 65 | + default=True, abort=False, prompt_suffix=': ', show_default=True, err=False |
| 66 | + ) |
| 67 | + click.echo("\nRunning: adb sideload <image>") |
| 68 | + if call(f'adb sideload {image}', shell=True) < 0: |
| 69 | + click.echo("*** Sideloading image failed! ***") |
| 70 | + return False |
| 71 | + |
| 72 | + click.echo("Flashing finished. Now press 'back' (arrow) and then 'Reboot system now' to finish the installation.") |
| 73 | + return True |
| 74 | + |
| 75 | + |
| 76 | +def boot_recovery(recovery: str): |
| 77 | + """ |
| 78 | + Temporarily booting a custom recovery using fastboot. |
| 79 | +
|
| 80 | + Using the recovery found in the path 'recovery'. |
| 81 | + """ |
| 82 | + # reboot into fastboot mode |
| 83 | + reboot_res = reboot_device_into_bootloader() |
| 84 | + if reboot_res == 4: |
| 85 | + click.echo("Unlocking the bootloader failed. Exiting.") |
| 86 | + return False |
| 87 | + # needs screen interaction here |
| 88 | + confirmed = click.confirm("Select 'Restart bootloader' on your smartphone screen. Then confirm", |
| 89 | + default=True, abort=False, prompt_suffix=': ', show_default=True, err=False) |
| 90 | + # list devices |
| 91 | + devices = run_fastboot_command(cmd=["devices"]) |
| 92 | + click.echo(f"Found: {devices}") |
| 93 | + # flash the recovery (temporarily) |
| 94 | + flash_result = run_fastboot_command(cmd=["flash", "boot", recovery]) |
| 95 | + click.echo("Recovery flashed successfully.") |
| 96 | + return True |
| 97 | + |
| 98 | + |
| 99 | +def reboot_device(): |
| 100 | + """Reboot the connected device.""" |
| 101 | + click.echo("\nRunning: fastboot reboot") |
| 102 | + if call('fastboot' + ' reboot', shell=True) < 0: |
| 103 | + click.echo("*** Reboot command failed! ***") |
| 104 | + return 4 |
| 105 | + return 0 |
| 106 | + |
| 107 | + |
| 108 | +def reboot_device_into_bootloader(): |
| 109 | + """Reboot the connected device into fastboot.""" |
| 110 | + click.echo("\nRunning: adb reboot bootloader") |
| 111 | + if call('adb reboot bootloader', shell=True) < 0: |
| 112 | + click.echo("*** Reboot-bootloader command failed! ***") |
| 113 | + return 4 |
| 114 | + return 0 |
| 115 | + |
| 116 | + |
| 117 | +def unlock_bootloader(): |
| 118 | + """Function to unlock the bootloader.""" |
| 119 | + # reboot into fastboot mode |
| 120 | + reboot_res = reboot_device_into_bootloader() |
| 121 | + if reboot_res == 4: |
| 122 | + click.echo("Unlocking the bootloader failed. Exiting.") |
| 123 | + return False |
| 124 | + # needs screen interaction here |
| 125 | + confirmed = click.confirm("Select 'Restart bootloader' on your smartphone screen. Then confirm", |
| 126 | + default=True, abort=False, prompt_suffix=': ', show_default=True, err=False) |
| 127 | + # list devices |
| 128 | + devices = run_fastboot_command(cmd=["devices"]) |
| 129 | + click.echo(f"Found: {devices}") |
| 130 | + # actually unlock the bootloader |
| 131 | + unlock_res = run_fastboot_command(cmd=["flashing", "unlock"]) |
| 132 | + click.echo(f"{unlock_res}") |
| 133 | + click.confirm("At this point the device may display on-screen prompts which will require interaction to continue the process of unlocking the bootloader. Please take whatever actions the device asks you to to proceed.", |
| 134 | + default=True, abort=False, prompt_suffix=': ', show_default=True, err=False |
| 135 | + ) |
| 136 | + # reboot device |
| 137 | + reboot_res = reboot_device() |
| 138 | + if reboot_res == 4: |
| 139 | + click.echo("Unlocking the bootloader failed while final reboot. Exiting.") |
| 140 | + return False |
| 141 | + click.echo("Bootloader is now unlocked!") |
| 142 | + click.echo( |
| 143 | + ">>Since the device resets completely, you will need to re-enable USB debugging to continue.") |
| 144 | + confirmed = click.confirm( |
| 145 | + "Confirm to continue", |
| 146 | + default=True, abort=False, prompt_suffix=': ', show_default=True, err=False |
| 147 | + ) |
| 148 | + return confirmed |
| 149 | + |
| 150 | + |
| 151 | +if __name__ == '__main__': |
| 152 | + install_lineage_os() |
0 commit comments