2024-05-13 14:30:34 +00:00
|
|
|
from . import files, exceptions
|
|
|
|
from .utils import logger, console
|
|
|
|
|
|
|
|
import os
|
|
|
|
import subprocess
|
|
|
|
|
|
|
|
|
|
|
|
def _fastboot_run(command: [str], serial: str = None) -> str:
|
|
|
|
try:
|
2024-05-16 18:28:42 +00:00
|
|
|
cmd = ["fastboot"]
|
2024-05-13 14:30:34 +00:00
|
|
|
if not serial:
|
2024-05-16 18:28:42 +00:00
|
|
|
cmd += command
|
2024-05-13 14:30:34 +00:00
|
|
|
else:
|
2024-05-16 18:28:42 +00:00
|
|
|
cmd += ["-s", serial] + command
|
|
|
|
logger.debug(f"fb-cmd: {cmd}")
|
|
|
|
fb_out = subprocess.check_output(cmd, stderr=subprocess.STDOUT, timeout=60)
|
|
|
|
logger.debug(f"fb-out: {fb_out}")
|
2024-05-13 14:30:34 +00:00
|
|
|
except FileNotFoundError:
|
|
|
|
console.log("Fastboot binary not found")
|
|
|
|
console.log("Exiting")
|
|
|
|
exit(1)
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
raise exceptions.DeviceNotFound("Timed out")
|
|
|
|
else:
|
|
|
|
return fb_out.decode()
|
|
|
|
|
|
|
|
|
|
|
|
def list_devices() -> [str]:
|
|
|
|
return list(
|
|
|
|
filter(
|
|
|
|
lambda x: x != "",
|
|
|
|
[x.split("\t ")[0] for x in _fastboot_run(["devices"]).split("\n")]
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def check_device(serial: str) -> bool:
|
|
|
|
return "nabu" in _fastboot_run(["getvar", "product"], serial=serial)
|
|
|
|
|
|
|
|
|
|
|
|
def check_parts(serial: str) -> bool:
|
|
|
|
linux_response = _fastboot_run(["getvar", "partition-type:linux"], serial=serial)
|
|
|
|
esp_response = _fastboot_run(["getvar", "partition-type:esp"], serial=serial)
|
|
|
|
logger.debug({
|
|
|
|
"esp": 'FAILED' not in esp_response,
|
|
|
|
"linux": 'FAILED' not in linux_response
|
|
|
|
})
|
|
|
|
return not ("FAILED" in linux_response or "FAILED" in esp_response)
|
|
|
|
|
|
|
|
|
|
|
|
def reboot(serial: str) -> None:
|
|
|
|
_fastboot_run(["reboot"], serial=serial)
|
|
|
|
|
|
|
|
|
|
|
|
def boot_ofox(serial: str) -> None:
|
|
|
|
files.OrangeFox.get()
|
|
|
|
ofox = files.OrangeFox.filepath
|
|
|
|
with console.status("[cyan]Booting", spinner="line", spinner_style="white"):
|
|
|
|
out = _fastboot_run(["boot", ofox], serial)
|
|
|
|
if "Failed to load/authenticate boot image: Device Error" in out:
|
2024-05-16 18:28:42 +00:00
|
|
|
raise exceptions.UnauthorizedBootImage("Failed to load/authenticate boot image: Device Error", out)
|
2024-05-13 14:30:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
def flash(serial: str, part: str, data: bytes) -> None:
|
|
|
|
with open("image.img", "wb") as file:
|
|
|
|
file.write(data)
|
|
|
|
|
|
|
|
with console.status(f"[cyan]Flashing {part}", spinner="line", spinner_style="white"):
|
|
|
|
_fastboot_run(["flash", part, "image.img"], serial=serial)
|
|
|
|
|
|
|
|
os.remove("image.img")
|
|
|
|
|
|
|
|
|
|
|
|
def restore_parts(serial: str) -> None:
|
|
|
|
gpt_both = files.GPT_Both0.get()
|
|
|
|
userdata = files.UserData_Empty.get()
|
|
|
|
flash(serial, "partition:0", gpt_both)
|
|
|
|
flash(serial, "userdata", userdata)
|
|
|
|
|
|
|
|
|
|
|
|
def clean_device(serial: str) -> None:
|
|
|
|
_fastboot_run(["erase", "linux"], serial=serial)
|
|
|
|
_fastboot_run(["erase", "esp"], serial=serial)
|
|
|
|
|
|
|
|
|
|
|
|
def wait_for_bootloader(serial: str) -> None:
|
|
|
|
_fastboot_run(["getvar", "product"], serial=serial)
|