Skip to content

Commit

Permalink
MVP for installing addons
Browse files Browse the repository at this point in the history
  • Loading branch information
tsterbak committed Jan 30, 2023
1 parent 97fd7be commit 2225d84
Show file tree
Hide file tree
Showing 5 changed files with 246 additions and 5 deletions.
25 changes: 22 additions & 3 deletions openandroidinstaller/openandroidinstaller.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@
InstallView,
WelcomeView,
AddonsView,
InstallAddonsView,
)
from tooling import run_command
from installer_config import Step

# where to write the logs
logger.add("openandroidinstaller.log")
Expand Down Expand Up @@ -113,9 +115,26 @@ def __init__(self, state: AppState):
self.state.final_view = self.final_view

# initialize the addon view
self.addon_view = AddonsView(on_confirm=self.confirm, state=self.state)
self.state.addon_view = self.addon_view

self.select_addon_view = AddonsView(on_confirm=self.confirm, state=self.state)
self.flash_recovery_view = StepView(
step=Step(
title="Flash custom recovery",
type="call_button",
content="Flash a custom recovery (temporarily) by pressing 'Confirm and run'. Once your phone screen looks like the picture on the left, continue.",
command="fastboot_flash_recovery",
img="twrp-start.jpeg",
),
state=self.state,
on_confirm=self.confirm,
)
self.install_addons_view = InstallAddonsView(
on_confirm=self.confirm, state=self.state
)
self.state.addon_views = [
self.install_addons_view,
self.flash_recovery_view,
self.select_addon_view,
]

def build(self):
self.view.controls.append(self.default_views.pop())
Expand Down
43 changes: 42 additions & 1 deletion openandroidinstaller/tooling.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,9 @@ def adb_twrp_copy_partitions(bin_path: Path, config_path: Path):
return True


def adb_twrp_wipe_and_install(bin_path: Path, target: str, config_path: Path, install_addons=True) -> bool:
def adb_twrp_wipe_and_install(
bin_path: Path, target: str, config_path: Path, install_addons=True
) -> bool:
"""Wipe and format data with twrp, then flash os image with adb.
Only works for twrp recovery.
Expand Down Expand Up @@ -237,6 +239,45 @@ def adb_twrp_wipe_and_install(bin_path: Path, target: str, config_path: Path, in
yield True


def adb_twrp_install_addons(bin_path: Path, addons: List[str]) -> bool:
"""Flash addons through adb and twrp.
Only works for twrp recovery.
"""
logger.info("Install addons with twrp.")
sleep(7)
# activate sideload
logger.info("Activate sideload.")
for line in run_command("adb", ["shell", "twrp", "sideload"], bin_path):
yield line
if (type(line) == bool) and not line:
logger.error("Activating sideload failed.")
yield False
return
# now flash os image
sleep(5)
logger.info("Sideload and install addons.")
for addon in addons:
for line in run_command("adb", ["sideload", f"{addon}"], bin_path):
yield line
if (type(line) == bool) and not line:
logger.error(f"Sideloading {addon} failed.")
# TODO: this might sometimes think it failed, but actually it's fine. So skip for now.
# yield False
# return
# finally reboot into os
sleep(7)
logger.info("Reboot into OS.")
for line in run_command("adb", ["reboot"], bin_path): # "shell", "twrp",
yield line
if (type(line) == bool) and not line:
logger.error("Rebooting failed.")
yield False
return
else:
yield True


def fastboot_unlock_with_code(bin_path: Path, unlock_code: str) -> bool:
"""Unlock the device with fastboot and code given."""
logger.info(f"Unlock the device with fastboot and code: {unlock_code}.")
Expand Down
1 change: 1 addition & 0 deletions openandroidinstaller/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
from .step_view import StepView # noqa
from .install_view import InstallView # noqa
from .addon_view import AddonsView # noqa
from .install_addons_view import InstallAddonsView # noqa
from .success_view import SuccessView # noqa
180 changes: 180 additions & 0 deletions openandroidinstaller/views/install_addons_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
"""Contains the install addons view."""

# This file is part of OpenAndroidInstaller.
# OpenAndroidInstaller is free software: you can redistribute it and/or modify it under the terms of
# the GNU General Public License as published by the Free Software Foundation,
# either version 3 of the License, or (at your option) any later version.

# OpenAndroidInstaller is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

# You should have received a copy of the GNU General Public License along with OpenAndroidInstaller.
# If not, see <https://www.gnu.org/licenses/>."""
# Author: Tobias Sterbak

from loguru import logger
from time import sleep
from typing import Callable

from flet import (
Column,
ElevatedButton,
Row,
Text,
icons,
Switch,
colors,
Markdown,
)

from views import BaseView
from app_state import AppState
from tooling import adb_twrp_install_addons
from widgets import (
confirm_button,
get_title,
)
from views.step_view import TerminalBox, ProgressIndicator


class InstallAddonsView(BaseView):
def __init__(
self,
state: AppState,
on_confirm: Callable,
):
super().__init__(state=state)
self.on_confirm = on_confirm

def build(self):
"""Create the content of the view."""
# error text
self.error_text = Text("", color=colors.RED)

# switch to enable advanced output - here it means show terminal input/output in tool
def check_advanced_switch(e):
"""Check the box to enable advanced output."""
if self.advanced_switch.value:
logger.info("Enable advanced output.")
self.state.advanced = True
self.terminal_box.toggle_visibility()
else:
logger.info("Disable advanced output.")
self.state.advanced = False
self.terminal_box.toggle_visibility()

self.advanced_switch = Switch(
label="Advanced output",
on_change=check_advanced_switch,
disabled=False,
)

# text box for terminal output
self.terminal_box = TerminalBox(expand=True)

# container for progress indicators
self.progress_indicator = ProgressIndicator(expand=True)

# main controls
self.right_view_header.controls = [
get_title(
"Install Addons",
step_indicator_img="steps-header-install.png",
)
]
self.right_view.controls = [
Markdown(
"""In the next steps, you finally flash the selected Addons.
Confirm to install.
This might take a while. At the end your phone will boot into the new OS.
"""
)
]
# basic view
logger.info("Starting addon installation.")
self.confirm_button = confirm_button(self.on_confirm)
self.confirm_button.disabled = True
# button to run the installation process
self.install_button = ElevatedButton(
"Confirm and install addons",
on_click=self.run_install_addons,
expand=True,
icon=icons.DIRECTIONS_RUN_OUTLINED,
)
# build the view
self.right_view.controls.extend(
[
Row([self.error_text]),
Row([self.progress_indicator]),
Column(
[
self.advanced_switch,
Row([self.install_button, self.confirm_button]),
]
),
Row([self.terminal_box]),
]
)

# if skipping is allowed add a button to the view
if self.state.test:
self.right_view.controls.append(
Row(
[
Text("Do you want to skip?"),
ElevatedButton(
"Skip",
on_click=self.on_confirm,
icon=icons.NEXT_PLAN_OUTLINED,
expand=True,
),
]
)
)
return self.view

def run_install_addons(self, e):
"""
Run the addon installation process trough twrp.
Some parts of the command are changed by placeholders.
"""
# disable the call button while the command is running
self.install_button.disabled = True
self.install_addons_switch.disabled = True
# reset the progress indicators
self.progress_indicator.clear()
# reset terminal output
if self.state.advanced:
self.terminal_box.clear()
self.right_view.update()

# run the install script
for line in adb_twrp_install_addons(
addons=self.state.addon_paths,
bin_path=self.state.bin_path,
):
# write the line to advanced output terminal
self.terminal_box.write_line(line)
# in case the install command is run, we want to update progress ring for now
self.progress_indicator.display_progress_ring()
success = line # the last element of the iterable is a boolean encoding success/failure

# update the view accordingly
if not success:
# enable call button to retry
self.install_button.disabled = False
# also remove the last error text if it happened
self.error_text.value = "Installation failed! Try again or make sure everything is setup correctly."
else:
sleep(5) # wait to make sure everything is fine
logger.success("Installation process was successful. Allow to continue.")
# enable the confirm button and disable the call button
self.confirm_button.disabled = False
self.install_button.disabled = True
# reset the progress indicator
self.progress_indicator.clear()
self.view.update()
2 changes: 1 addition & 1 deletion openandroidinstaller/views/install_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def check_addons_switch(e):
if self.install_addons_switch.value:
logger.info("Enable flashing addons.")
# add the addons step here.
self.state.default_views.append(self.state.addon_view)
self.state.default_views.extend(self.state.addon_views)
self.state.install_addons = True
else:
logger.info("Disable flashing addons.")
Expand Down

0 comments on commit 2225d84

Please sign in to comment.