Skip to content

Release 0.6.0-beta #233

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,18 @@ Linux is currently the best supported platform (tested with Ubuntu 20.04/22.04 L
1. Download the [.exe or appropriate executable file for your OS](https://github.com/openandroidinstaller-dev/openandroidinstaller/releases) from the releases or get the [official flatpak from flathub](https://flathub.org/apps/org.openandroidinstaller.OpenAndroidInstaller). You might need to change permissions to run the executable.
- On Windows also [install the Universal USB Drivers](https://adb.clockworkmod.com/) and other potentially drivers needed for your device.
2. Download the custom ROM image and the TWRP recovery image for your device and optionally some addons. A source for files can be found on the following websites:
- some custom ROMs:
- Some custom ROMs:
- [LineageOS](https://wiki.lineageos.org/devices)
- [/e/OS](https://doc.e.foundation/devices)
- [LineageOS for microg](https://download.lineage.microg.org)
- [BlissRoms](https://blissroms.org)
- [PixelExperience](https://download.pixelexperience.org)
- TWRP Recovery:
- [crDroid](https://crdroid.net/)
- [ArrowOS](https://arrowos.net/)
- [DivestOS](https://divestos.org/)
- Recoveries:
- [TWRP recovery](https://twrp.me/Devices)
- [OrangeFox](https://wiki.orangefox.tech)
- Optional Addons:
- There are different packages of *Google Apps* available.
- [MindTheGapps](https://wiki.lineageos.org/gapps#downloads)
Expand Down Expand Up @@ -214,6 +218,7 @@ Every config file should have `metadata` with the following fields:
- `is_ab_device`: bool; A boolean to determine if the device is a/b-partitioned or not.
- `device_code`: str; The official device code.
- `supported_device_codes`: List[str]; A list of supported device codes for the config. The config will be loaded based on this field.
- `supported_recovery`: [OPTIONAL] List[str]; A list of supported recoveries. For the moment, can be twrp and/or orangefox (twrp by default)
- `twrp-link`: [OPTIONAL] str; name of the corresponding twrp page.

In addition to these metadata, every config can have optional `requirements`. If these are set, the user is asked to check if they are meet.
Expand Down
1 change: 1 addition & 0 deletions openandroidinstaller/app_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def __init__(
self.config = None
self.image_path = None
self.recovery_path = None
self.chosen_recovery = None

# store views
self.default_views: List = []
Expand Down
Binary file added openandroidinstaller/assets/imgs/ofox.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion openandroidinstaller/installer_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def __init__(
self.is_ab = metadata.get("is_ab_device", False)
self.supported_device_codes = metadata.get("supported_device_codes")
self.twrp_link = metadata.get("twrp-link")
self.supported_recovery = metadata.get("supported_recovery", ["twrp"]) # if it is not given, we assume TWRP

@classmethod
def from_file(cls, path):
Expand Down Expand Up @@ -150,7 +151,7 @@ def validate_config(config: str) -> bool:
),
"content": str,
schema.Optional("command"): Regex(
r"adb_reboot|adb_reboot_bootloader|adb_reboot_download|adb_sideload|adb_twrp_wipe_and_install|adb_twrp_copy_partitions|fastboot_boot_recovery|fastboot_flash_boot|fastboot_unlock_with_code|fastboot_get_unlock_data|fastboot_unlock|fastboot_oem_unlock|fastboot_reboot|heimdall_flash_recovery"
r"adb_reboot|adb_reboot_bootloader|adb_reboot_download|adb_sideload|adb_twrp_wipe_and_install|adb_twrp_copy_partitions|fastboot_boot_recovery|fastboot_flash_recovery|fastboot_reboot_recovery|fastboot_flash_boot|fastboot_unlock_with_code|fastboot_get_unlock_data|fastboot_unlock|fastboot_oem_unlock|fastboot_reboot|heimdall_flash_recovery"
),
schema.Optional("allow_skip"): bool,
schema.Optional("img"): str,
Expand All @@ -166,6 +167,7 @@ def validate_config(config: str) -> bool:
"device_code": str,
"supported_device_codes": [str],
schema.Optional("twrp-link"): str,
schema.Optional("supported_recovery"): [str],
},
schema.Optional("requirements"): {
schema.Optional("android"): schema.Or(str, int),
Expand Down
105 changes: 78 additions & 27 deletions openandroidinstaller/tooling.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,15 @@ def activate_sideload(bin_path: Path) -> TerminalResponse:
yield line


@add_logging("Activate sideloading in OranfeFox.", return_if_fail=True)
def activate_sideload_ofox(bin_path: Path) -> TerminalResponse:
"""Activate sideload with adb shell in OrangeFox."""
for line in run_command(
"adb shell twrp sideload help", bin_path
): # Why help ? Don't know, but it works
yield line


@add_logging("Wait for device")
def adb_wait_for_device(bin_path: Path) -> TerminalResponse:
"""Use adb to wait for the device to become available."""
Expand Down Expand Up @@ -216,14 +225,15 @@ def adb_twrp_wipe_and_install(
target: str,
config_path: Path,
is_ab: bool,
chosen_recovery: str,
install_addons=True,
recovery: Optional[str] = None,
) -> TerminalResponse:
"""Wipe and format data with twrp, then flash os image with adb.
"""Wipe and format data with recovery, then flash os image with adb.

Only works for twrp recovery.
Only works for twrp and OrangeFox recovery.
"""
logger.info("Wipe and format data with twrp, then install os image.")
logger.info(f"Wipe and format data with {chosen_recovery}, then install os image.")
for line in adb_wait_for_recovery(bin_path):
yield line

Expand All @@ -233,38 +243,46 @@ def adb_twrp_wipe_and_install(

sleep(1)
# wipe some partitions
for partition in ["cache", "system"]:
for partition in ["cache", "dalvik", "system"]:
for line in adb_twrp_wipe_partition(bin_path=bin_path, partition=partition):
yield line
sleep(1)

# activate sideload
logger.info("Wiping is done, now activate sideload.")
for line in activate_sideload(bin_path=bin_path):
yield line
logger.info(f"Wiping is done, now activate sideload with {chosen_recovery}.")
if chosen_recovery == "orangefox":
for line in activate_sideload_ofox(bin_path=bin_path):
yield line
else:
for line in activate_sideload(bin_path=bin_path):
yield line
sleep(5)
# now flash os image
logger.info("Sideload and install os image.")
for line in adb_sideload(bin_path=bin_path, target=target):
yield line
# wipe some cache partitions
sleep(7)
for partition in ["dalvik", "cache"]:
for line in run_command(f"adb shell twrp wipe {partition}", bin_path):
yield line
sleep(3)
if (type(line) == bool) and not line:
logger.error(f"Wiping {partition} failed.")
# TODO: if this fails, a fix can be to just sideload something and then adb reboot
for line in adb_sideload(
target=f"{config_path.parent.joinpath(Path('helper.txt'))}",
bin_path=bin_path,
):
# wipe some cache partitions
if (chosen_recovery != "orangefox"):
# OrangeFox go in buggy sideload mode when wiping dalvik here (and already been wiped before)
logger.info("Wiping cache and dalvik...")
for partition in ["dalvik", "cache"]:
for line in run_command(f"adb shell twrp wipe {partition}", bin_path):
yield line
sleep(1)
sleep(2)
if (type(line) == bool) and not line:
yield False
break
sleep(2)
logger.error(f"Wiping {partition} failed.")
# TODO: if this fails, a fix can be to just sideload something and then adb reboot
for line in adb_sideload(
target=f"{config_path.parent.joinpath(Path('helper.txt'))}",
bin_path=bin_path,
):
yield line
sleep(1)
if (type(line) == bool) and not line:
yield False
break
sleep(2)
# finally reboot into os or to fastboot for flashing addons
for line in adb_wait_for_recovery(bin_path):
yield line
Expand All @@ -288,20 +306,25 @@ def adb_twrp_wipe_and_install(


def adb_twrp_install_addon(
bin_path: Path, addon_path: str, is_ab: bool
bin_path: Path, addon_path: str, chosen_recovery: str, is_ab: bool
) -> TerminalResponse:
"""Flash addon through adb and twrp.

Only works for twrp recovery.
"""
logger.info(f"Install addon {addon_path} with twrp.")
logger.info(f"Install addon {addon_path} with {chosen_recovery}.")
sleep(0.5)
if is_ab:
adb_wait_for_recovery(bin_path=bin_path)
# activate sideload
logger.info("Activate sideload.")
for line in activate_sideload(bin_path=bin_path):
yield line
if chosen_recovery == "orangefox":
for line in activate_sideload_ofox(bin_path=bin_path):
yield line
else:
for line in activate_sideload(bin_path=bin_path):
yield line
sleep(5)
logger.info("Sideload and install addon.")
# now flash the addon
for line in adb_sideload(bin_path=bin_path, target=addon_path):
Expand Down Expand Up @@ -440,6 +463,34 @@ def fastboot_flash_boot(bin_path: Path, recovery: str) -> TerminalResponse:
yield True


@add_logging("Flash custom recovery with fastboot.")
def fastboot_flash_recovery(
bin_path: Path, recovery: str, is_ab: bool = True
) -> TerminalResponse:
"""Flash custom recovery with fastboot."""
for line in run_command(
"fastboot flash recovery ", target=f"{recovery}", bin_path=bin_path
):
yield line
if not is_ab:
if (type(line) == bool) and not line:
logger.error("Flashing recovery failed.")
yield False
else:
yield True


@add_logging("Rebooting device to recovery.")
def fastboot_reboot_recovery(bin_path: Path) -> TerminalResponse:
"""
Reboot to recovery with fastboot

WARNING : On some devices, users should perform a key combo
"""
for line in run_command("fastboot reboot recovery", bin_path):
yield line


def heimdall_wait_for_download_available(bin_path: Path) -> bool:
"""Use heimdall detect to wait for download mode to become available on the device."""
logger.info("Wait for download mode to become available.")
Expand Down
41 changes: 35 additions & 6 deletions openandroidinstaller/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,44 @@ def image_works_with_device(supported_device_codes: List[str], image_path: str)
return False


def recovery_works_with_device(device_code: str, recovery_path: str) -> bool:
def recovery_works_with_device(
supported_device_codes: [str], supported_recovery: [str], recovery_path: str
) -> bool:
"""Determine if a recovery works for the given device.

BEWARE: THE RECOVERY PART IS STILL VERY BASIC!
"""
recovery_file_name = recovery_path.split("/")[-1]
if (device_code in recovery_file_name) and ("twrp" in recovery_file_name):
logger.success("Device supported by the selected recovery.")
return True
else:
logger.error(f"Recovery file {recovery_file_name} is not supported.")
if recovery_file_name[-4:] != ".img":
logger.error(f"The file {recovery_file_name} is not a recovery file")
return False
for codename in supported_device_codes:
if (
(codename in recovery_file_name)
and ("twrp" in recovery_file_name.lower())
and ("twrp" in supported_recovery)
):
logger.success("Selected recovery supported for this device.")
return True
elif recovery_file_name == "recovery.img" and (
"orangefox" in supported_recovery
):
logger.error("Cannot check recovery. Supposing it is OrangeFox.")
return True
logger.error(f"Recovery file {recovery_file_name} is not supported.")
return False


def which_recovery_from_path(recovery_path: str) -> str:
"""Determine which recovery was selected

This does not replace recovery_works_with_device.
BEWARE: THE RECOVERY PART IS STILL VERY BASIC!
"""
recovery_file_name = recovery_path.split("/")[-1]
if "twrp" in recovery_file_name or "TWRP" in recovery_file_name:
return "twrp"
if recovery_file_name == "recovery.img":
return "orangefox"
logger.error("Unable to determine which recovery was selected !")
return None
1 change: 1 addition & 0 deletions openandroidinstaller/views/install_addons_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ def run_install_addons(self, e):
for line in adb_twrp_install_addon(
addon_path=addon_path,
bin_path=self.state.bin_path,
chosen_recovery=self.state.chosen_recovery,
is_ab=self.state.config.is_ab,
):
# write the line to advanced output terminal
Expand Down
3 changes: 2 additions & 1 deletion openandroidinstaller/views/install_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def check_addons_switch(e):

def run_install(self, e):
"""
Run the installation process through twrp.
Run the installation process through recovery.

Some parts of the command are changed by placeholders.
"""
Expand All @@ -193,6 +193,7 @@ def run_install(self, e):
bin_path=self.state.bin_path,
install_addons=self.state.install_addons,
is_ab=self.state.config.is_ab,
chosen_recovery=self.state.chosen_recovery,
recovery=self.state.recovery_path,
):
# write the line to advanced output terminal
Expand Down
Loading