1758 lines
29 KiB
Markdown
1758 lines
29 KiB
Markdown
# A-Team Android ROM Builder — Technical Documentation
|
|
|
|
## 1. Purpose
|
|
|
|
A-Team Android ROM Builder is a Python/GTK 3 application that provides a graphical project-management layer around Android ROM development.
|
|
|
|
The application is deliberately split into two major areas:
|
|
|
|
1. **Python application/backend**
|
|
- GUI
|
|
- project state
|
|
- configuration loading
|
|
- environment generation
|
|
- profile management
|
|
- terminal integration
|
|
- resource monitoring
|
|
- host management
|
|
- updater handling
|
|
|
|
2. **Bash/script layer**
|
|
- ROM synchronization
|
|
- device setup
|
|
- GApps synchronization
|
|
- ROM building
|
|
- cleaning
|
|
- uploading
|
|
- device-specific patches and setup
|
|
|
|
This separation is one of the most important architectural characteristics of the project.
|
|
|
|
The GUI should generally manage **what** project is being operated on, while scripts determine **how** the Android source tree is synchronized, modified, built, cleaned, or uploaded.
|
|
|
|
---
|
|
|
|
## 2. High-Level Architecture
|
|
|
|
```text
|
|
gui.py
|
|
|
|
|
+-------------+-------------+
|
|
| | |
|
|
v v v
|
|
Project Configs UI Managers
|
|
| | |
|
|
+-------------+-------------+
|
|
|
|
|
v
|
|
Project.as_environment()
|
|
|
|
|
v
|
|
Script / Action Layer
|
|
|
|
|
+------------+------------+
|
|
| | |
|
|
v v v
|
|
sync.sh build.sh clean.sh
|
|
|
|
|
v
|
|
device sync scripts
|
|
|
|
|
v
|
|
Android ROM tree
|
|
```
|
|
|
|
The GUI owns project selections.
|
|
|
|
The `Project` object converts those selections and configuration files into an environment that scripts consume.
|
|
|
|
---
|
|
|
|
# 3. Main Application Entry Point
|
|
|
|
The primary entry point is:
|
|
|
|
```text
|
|
gui.py
|
|
```
|
|
|
|
The application initializes GTK, creates the `ROMBuilder` window, and constructs the application's tabs.
|
|
|
|
The current interface contains:
|
|
|
|
```text
|
|
1- Build Setup
|
|
2- Sync & Setup Device Source
|
|
3- Build
|
|
Terminal
|
|
Resource Monitor
|
|
Tools
|
|
```
|
|
|
|
The exact tab construction is contained in `ROMBuilder`.
|
|
|
|
---
|
|
|
|
# 4. Python Backend
|
|
|
|
The `builder/` directory contains the application backend.
|
|
|
|
Current major modules include:
|
|
|
|
```text
|
|
builder/
|
|
├── actions.py
|
|
├── button_actions.py
|
|
├── config_loader.py
|
|
├── device_manager.py
|
|
├── hosts_manager.py
|
|
├── icon_manager.py
|
|
├── launcher_shortcut.py
|
|
├── profile_manager.py
|
|
├── project.py
|
|
├── project_loader.py
|
|
├── project_summary.py
|
|
├── resource_monitor.py
|
|
├── script_runner.py
|
|
├── splash.py
|
|
├── splash_manager.py
|
|
├── terminal.py
|
|
├── updater.py
|
|
├── updater_overlay.py
|
|
└── version.py
|
|
```
|
|
|
|
The backend is intentionally separated from GTK-specific code wherever practical.
|
|
|
|
---
|
|
|
|
# 5. Configuration Loader
|
|
|
|
`builder/config_loader.py` contains the basic configuration parser.
|
|
|
|
It reads simple:
|
|
|
|
```text
|
|
KEY=VALUE
|
|
```
|
|
|
|
files.
|
|
|
|
Supported behavior includes:
|
|
|
|
- Blank lines are ignored
|
|
- Lines beginning with `#` are comments
|
|
- Lines without `=` are ignored
|
|
- Values may be surrounded by single or double quotes
|
|
- `~` is expanded to the user's home directory
|
|
|
|
Example:
|
|
|
|
```text
|
|
DEVICE_CODENAME="milanf"
|
|
DEVICE_SOC="sm6375"
|
|
ROM_DISPLAY_NAME="LineageOS"
|
|
```
|
|
|
|
becomes a Python dictionary:
|
|
|
|
```python
|
|
{
|
|
"DEVICE_CODENAME": "milanf",
|
|
"DEVICE_SOC": "sm6375",
|
|
"ROM_DISPLAY_NAME": "LineageOS"
|
|
}
|
|
```
|
|
|
|
This deliberately simple format makes configuration files easy to edit from a terminal or text editor.
|
|
|
|
---
|
|
|
|
# 6. Device Discovery
|
|
|
|
Device discovery is handled by:
|
|
|
|
```text
|
|
builder/device_manager.py
|
|
```
|
|
|
|
The application scans:
|
|
|
|
```text
|
|
configs/devices/
|
|
```
|
|
|
|
for `.conf` files.
|
|
|
|
A device does not need to be hard-coded into the GUI.
|
|
|
|
This means adding a properly formatted configuration file is the primary mechanism for adding a device.
|
|
|
|
The device manager reads:
|
|
|
|
```text
|
|
DEVICE_DISPLAY_NAME
|
|
```
|
|
|
|
for the user-facing device name.
|
|
|
|
If it is not present, the configuration filename is used as a fallback display name.
|
|
|
|
The device list is sorted by display name.
|
|
|
|
---
|
|
|
|
# 7. Adding a New Device
|
|
|
|
To add a new device, create:
|
|
|
|
```text
|
|
configs/devices/<device_name>.conf
|
|
```
|
|
|
|
For example:
|
|
|
|
```text
|
|
configs/devices/example.conf
|
|
```
|
|
|
|
A practical device configuration should define the device identity and the variables required by its scripts.
|
|
|
|
Example:
|
|
|
|
```text
|
|
DEVICE_CODENAME="example"
|
|
DEVICE_DISPLAY_CODENAME="Example"
|
|
DEVICE_DISPLAY_NAME="Example Android Device"
|
|
DEVICE_KERNEL="5.4"
|
|
DEVICE_SOC="smXXXX"
|
|
DEVICE_MANUFACTURER="Motorola"
|
|
DEVICE_MODEL_NUMBER="XTXXXX"
|
|
DEVICE_SYNC_SCRIPT="example-sync.sh"
|
|
```
|
|
|
|
### Important variables
|
|
|
|
#### `DEVICE_CODENAME`
|
|
|
|
The Android/device-tree codename used by scripts.
|
|
|
|
Example:
|
|
|
|
```text
|
|
DEVICE_CODENAME="milanf"
|
|
```
|
|
|
|
#### `DEVICE_DISPLAY_CODENAME`
|
|
|
|
Human-readable short name used in messages.
|
|
|
|
```text
|
|
DEVICE_DISPLAY_CODENAME="Milanf"
|
|
```
|
|
|
|
#### `DEVICE_DISPLAY_NAME`
|
|
|
|
Name shown in the GUI device selector.
|
|
|
|
```text
|
|
DEVICE_DISPLAY_NAME="Moto G Stylus 5G 2022"
|
|
```
|
|
|
|
#### `DEVICE_SYNC_SCRIPT`
|
|
|
|
Name of the device-specific synchronization script.
|
|
|
|
```text
|
|
DEVICE_SYNC_SCRIPT="milanf-sync.sh"
|
|
```
|
|
|
|
The main `scripts/sync.sh` script uses this value to locate:
|
|
|
|
```text
|
|
scripts/devices_sync/<DEVICE_SYNC_SCRIPT>
|
|
```
|
|
|
|
### Device-specific variables
|
|
|
|
Any additional variables can be added to the device configuration.
|
|
|
|
For example:
|
|
|
|
```text
|
|
DEVICE_KERNEL="5.4"
|
|
DEVICE_SOC="sm6375"
|
|
DEVICE_MANUFACTURER="Motorola"
|
|
DEVICE_MODEL_NUMBER="XT2215"
|
|
```
|
|
|
|
Those values become part of the project environment and can therefore be consumed by Bash scripts.
|
|
|
|
---
|
|
|
|
# 8. Device Sync Scripts
|
|
|
|
Device-specific sync scripts live under:
|
|
|
|
```text
|
|
scripts/devices_sync/
|
|
```
|
|
|
|
A device configuration selects its script with:
|
|
|
|
```text
|
|
DEVICE_SYNC_SCRIPT="example-sync.sh"
|
|
```
|
|
|
|
The main synchronization flow effectively becomes:
|
|
|
|
```text
|
|
scripts/sync.sh
|
|
|
|
|
+--> load device configuration
|
|
|
|
|
+--> A-Team setup
|
|
|
|
|
+--> determine DEVICE_SYNC_SCRIPT
|
|
|
|
|
+--> cd "$ROM_PATH"
|
|
|
|
|
+--> run scripts/devices_sync/<device-script>
|
|
```
|
|
|
|
This allows each device to have completely different synchronization or patching requirements without turning the main GUI into a collection of device-specific conditionals.
|
|
|
|
---
|
|
|
|
# 9. Project Object
|
|
|
|
`builder/project.py` contains the `Project` dataclass.
|
|
|
|
Important project state includes:
|
|
|
|
```text
|
|
profile_name
|
|
host_name
|
|
device_name
|
|
rom_name
|
|
rom_branch
|
|
android_version
|
|
rom_path
|
|
build_variant
|
|
build_command
|
|
gapps_variant
|
|
clean_variant
|
|
installer_variant
|
|
build_jobs
|
|
use_ccache
|
|
custom_apn
|
|
device_vars
|
|
rom_vars
|
|
rom_config_path
|
|
setup_vars
|
|
upload_vars
|
|
```
|
|
|
|
This object is the central representation of the currently selected project.
|
|
|
|
---
|
|
|
|
# 10. ROM Path Interpretation
|
|
|
|
When a ROM source path is selected, `Project.set_rom_path()` derives:
|
|
|
|
```text
|
|
ROM_BRANCH
|
|
ROM_NAME
|
|
```
|
|
|
|
from the directory structure.
|
|
|
|
For a path such as:
|
|
|
|
```text
|
|
/home/pizzag/Android/Roms/Lineage/23.2
|
|
```
|
|
|
|
the project interprets:
|
|
|
|
```text
|
|
ROM_NAME = Lineage
|
|
ROM_BRANCH = 23.2
|
|
ROM_PATH = /home/pizzag/Android/Roms/Lineage/23.2
|
|
```
|
|
|
|
This is important because the scripts receive these values automatically.
|
|
|
|
---
|
|
|
|
# 11. ROM Configuration System
|
|
|
|
There are two supported locations for the ROM configuration.
|
|
|
|
### Application-level default
|
|
|
|
```text
|
|
configs/rom.conf
|
|
```
|
|
|
|
### ROM-local override
|
|
|
|
```text
|
|
<ROM_ROOT>/rom.conf
|
|
```
|
|
|
|
The loader checks the selected ROM root first.
|
|
|
|
If:
|
|
|
|
```text
|
|
<ROM_ROOT>/rom.conf
|
|
```
|
|
|
|
exists, it is loaded.
|
|
|
|
Otherwise:
|
|
|
|
```text
|
|
configs/rom.conf
|
|
```
|
|
|
|
is loaded.
|
|
|
|
This allows a ROM tree to carry its own configuration.
|
|
|
|
### Example
|
|
|
|
Builder:
|
|
|
|
```text
|
|
A-Team-Android_ROM_Builder/
|
|
└── configs/
|
|
└── rom.conf
|
|
```
|
|
|
|
ROM:
|
|
|
|
```text
|
|
Lineage/
|
|
└── 23.2/
|
|
├── build/
|
|
├── device/
|
|
├── vendor/
|
|
└── rom.conf
|
|
```
|
|
|
|
The second file overrides the builder-level ROM configuration for that project.
|
|
|
|
### Case sensitivity
|
|
|
|
The loader currently checks for:
|
|
|
|
```text
|
|
rom.conf
|
|
```
|
|
|
|
in lowercase.
|
|
|
|
On Linux:
|
|
|
|
```text
|
|
rom.conf
|
|
ROM.conf
|
|
Rom.conf
|
|
```
|
|
|
|
are different filenames.
|
|
|
|
The build-command dropdown may display a human-readable entry such as:
|
|
|
|
```text
|
|
Default --> Rom.conf
|
|
```
|
|
|
|
but the actual loader filename is:
|
|
|
|
```text
|
|
rom.conf
|
|
```
|
|
|
|
---
|
|
|
|
# 12. ROM Configuration Variables
|
|
|
|
The ROM configuration is not restricted to a fixed set of variables.
|
|
|
|
Example:
|
|
|
|
```text
|
|
M="make"
|
|
|
|
CCACHE_SIZE="300"
|
|
|
|
DEFAULT_ROM_BUILD_COMMAND="brunch $DEVICE_CODENAME"
|
|
|
|
ROM_BUILD_NAME=lineage
|
|
ROM_TARGET_RELEASE="bp4a"
|
|
ROM_FINAL_LOCATION="~/Desktop/Release_Test"
|
|
ROM_BUILD_ZIP_NAME="*-UNOFFICIAL-$DEVICE_CODENAME.zip"
|
|
ROM_DISPLAY_NAME="LineageOS"
|
|
ROM_VENDOR_NAME=lineage
|
|
ROM_MANIFEST="https://github.com/LineageOS/android.git"
|
|
ROM_BRANCH_PREFIX="lineage-"
|
|
ROM_MAJOR_VERSION="23"
|
|
ROM_MINOR_VERSION="2"
|
|
```
|
|
|
|
Additional variables can be added when scripts require them.
|
|
|
|
---
|
|
|
|
# 13. Variable Resolution
|
|
|
|
`Project.as_environment()` combines several sources of variables.
|
|
|
|
The environment begins with GUI/project values.
|
|
|
|
Examples:
|
|
|
|
```text
|
|
DEVICE_NAME
|
|
ROM_NAME
|
|
ROM_BRANCH
|
|
ROM_PATH
|
|
ANDROID_VERSION
|
|
BUILD_VARIANT
|
|
BUILD_COMMAND
|
|
GAPPS_VARIANT
|
|
CLEAN_VARIANT
|
|
INSTALLER_VARIANT
|
|
BUILD_JOBS
|
|
USE_CCACHE
|
|
APN_VARIANT
|
|
```
|
|
|
|
Then configuration dictionaries are merged:
|
|
|
|
```text
|
|
device_vars
|
|
rom_vars
|
|
setup_vars
|
|
upload_vars
|
|
```
|
|
|
|
The project then resolves references such as:
|
|
|
|
```text
|
|
$DEVICE_CODENAME
|
|
${DEVICE_CODENAME}
|
|
```
|
|
|
|
Nested variable references are supported through repeated resolution passes.
|
|
|
|
This allows a ROM configuration to contain:
|
|
|
|
```text
|
|
DEFAULT_ROM_BUILD_COMMAND="brunch $DEVICE_CODENAME"
|
|
```
|
|
|
|
without requiring Python code to know what the device codename is.
|
|
|
|
---
|
|
|
|
# 14. Environment Precedence
|
|
|
|
The environment is constructed approximately in this order:
|
|
|
|
```text
|
|
Base project variables
|
|
|
|
|
v
|
|
Device variables
|
|
|
|
|
v
|
|
ROM variables
|
|
|
|
|
v
|
|
A-Team setup variables
|
|
|
|
|
v
|
|
Upload variables
|
|
|
|
|
v
|
|
Variable reference resolution
|
|
```
|
|
|
|
Therefore, configuration values should be named carefully to avoid unintentionally overriding a project variable.
|
|
|
|
---
|
|
|
|
# 15. Build Commands
|
|
|
|
The Build tab reads:
|
|
|
|
```text
|
|
configs/rom_build_commands.conf
|
|
```
|
|
|
|
The current file can contain entries such as:
|
|
|
|
```text
|
|
Default --> Rom.conf
|
|
Lineage
|
|
Derpfest
|
|
```
|
|
|
|
Lines beginning with `#` and blank lines are ignored.
|
|
|
|
Entries containing:
|
|
|
|
```text
|
|
-->
|
|
```
|
|
|
|
are treated as display-only entries by the current loader.
|
|
|
|
Normal entries are converted into a lowercase command value.
|
|
|
|
The selected command becomes:
|
|
|
|
```text
|
|
BUILD_COMMAND
|
|
```
|
|
|
|
in the project environment.
|
|
|
|
This makes it possible to expand the GUI's build command selector without modifying the Build tab itself.
|
|
|
|
---
|
|
|
|
# 16. Build Execution
|
|
|
|
The Build button calls the action layer.
|
|
|
|
The action layer creates a temporary environment shell file containing the current project variables.
|
|
|
|
Conceptually:
|
|
|
|
```bash
|
|
export DEVICE_NAME='milanf'
|
|
export ROM_NAME='Lineage'
|
|
export ROM_BRANCH='23.2'
|
|
export ROM_PATH='/home/pizzag/...'
|
|
export ANDROID_VERSION='16'
|
|
...
|
|
```
|
|
|
|
The requested script is then executed.
|
|
|
|
The build script is:
|
|
|
|
```text
|
|
scripts/build.sh
|
|
```
|
|
|
|
The GUI therefore does not need to contain the ROM's actual build command logic.
|
|
|
|
---
|
|
|
|
# 17. Script Execution
|
|
|
|
`builder/script_runner.py` provides generic script execution.
|
|
|
|
It:
|
|
|
|
1. Copies the current process environment.
|
|
2. Adds `project.as_environment()`.
|
|
3. Verifies that the script exists.
|
|
4. Executes it with Bash.
|
|
5. Returns the exit status.
|
|
|
|
The action layer provides another mechanism that is useful when the GUI needs a shell command containing the generated environment.
|
|
|
|
This architecture allows scripts to remain independently testable.
|
|
|
|
For example, a script can generally be debugged directly from a terminal after exporting the required variables.
|
|
|
|
---
|
|
|
|
# 18. Sync Workflow
|
|
|
|
The main synchronization entry point is:
|
|
|
|
```text
|
|
scripts/sync.sh
|
|
```
|
|
|
|
It:
|
|
|
|
1. Determines the builder root.
|
|
2. Locates the device configuration.
|
|
3. Checks for the A-Team setup marker.
|
|
4. Installs/runs the A-Team addon setup when necessary.
|
|
5. Determines the selected device synchronization script.
|
|
6. Changes to the selected ROM source.
|
|
7. Runs the device-specific synchronization script.
|
|
|
|
The device setup marker is stored under the ROM tree:
|
|
|
|
```text
|
|
device/A-Team/A-Team-Setup.check
|
|
```
|
|
|
|
When the marker exists, the main A-Team setup is skipped.
|
|
|
|
This avoids repeatedly performing setup operations on the same ROM tree.
|
|
|
|
---
|
|
|
|
# 19. MindTheGapps Synchronization
|
|
|
|
The GApps script is:
|
|
|
|
```text
|
|
scripts/gapps_sync.sh
|
|
```
|
|
|
|
The script selects the MindTheGapps branch from `ANDROID_VERSION`.
|
|
|
|
The current mapping includes:
|
|
|
|
```text
|
|
Android 16 -> baklava
|
|
Android 17 -> cinnamonbun
|
|
```
|
|
|
|
The destination is:
|
|
|
|
```text
|
|
$ROM_PATH/vendor/gapps
|
|
```
|
|
|
|
The existing GApps source is removed before cloning the selected branch.
|
|
|
|
Git LFS assets are then pulled.
|
|
|
|
---
|
|
|
|
# 20. Build Options
|
|
|
|
The GUI currently exposes several build-related selections.
|
|
|
|
### Android Version
|
|
|
|
Current GUI options include:
|
|
|
|
```text
|
|
16
|
|
17
|
|
```
|
|
|
|
The selected value becomes:
|
|
|
|
```text
|
|
ANDROID_VERSION
|
|
```
|
|
|
|
### Build Variant
|
|
|
|
Current options include:
|
|
|
|
```text
|
|
Userdebug
|
|
Eng
|
|
User
|
|
```
|
|
|
|
The internal project values are lowercase equivalents.
|
|
|
|
### GApps Variant
|
|
|
|
Current options include:
|
|
|
|
```text
|
|
Vanilla
|
|
Gapps
|
|
Micro-G
|
|
Foss
|
|
```
|
|
|
|
### Clean Variant
|
|
|
|
Current options include:
|
|
|
|
```text
|
|
Full
|
|
Lite
|
|
None
|
|
```
|
|
|
|
### Installer Variant
|
|
|
|
Current options include:
|
|
|
|
```text
|
|
Custom A-Team ROM Installer
|
|
Default ROM Installer
|
|
```
|
|
|
|
### Build Jobs
|
|
|
|
The Build Jobs control determines the parallel job count passed into the project.
|
|
|
|
### Ccache
|
|
|
|
The Ccache checkbox controls:
|
|
|
|
```text
|
|
USE_CCACHE
|
|
```
|
|
|
|
### Custom APN
|
|
|
|
The Custom APN checkbox controls:
|
|
|
|
```text
|
|
APN_VARIANT
|
|
```
|
|
|
|
The current project environment represents enabled/disabled boolean selections using the values expected by the existing script layer.
|
|
|
|
---
|
|
|
|
# 21. Project Profiles
|
|
|
|
Project profiles are JSON files stored in:
|
|
|
|
```text
|
|
profiles/
|
|
```
|
|
|
|
A profile can preserve:
|
|
|
|
```text
|
|
profile_name
|
|
host_name
|
|
device_name
|
|
rom_path
|
|
android_version
|
|
build_variant
|
|
build_command
|
|
gapps_variant
|
|
clean_variant
|
|
installer_variant
|
|
build_jobs
|
|
use_ccache
|
|
custom_apn
|
|
```
|
|
|
|
Profiles are useful for repeatedly building the same device/ROM combination.
|
|
|
|
A profile does not replace the device or ROM configuration files.
|
|
|
|
Instead, it stores the user's selected project state and the configuration system is still loaded when the project is used.
|
|
|
|
---
|
|
|
|
# 22. Build Hosts
|
|
|
|
Hosts are managed by:
|
|
|
|
```text
|
|
builder/hosts_manager.py
|
|
```
|
|
|
|
Configuration:
|
|
|
|
```text
|
|
configs/hosts.conf
|
|
```
|
|
|
|
The format is INI-style.
|
|
|
|
Example:
|
|
|
|
```ini
|
|
[Local]
|
|
type=local
|
|
|
|
[BuildServer]
|
|
type=ssh
|
|
server_address=192.168.1.100
|
|
port=22
|
|
user=pizzag
|
|
remote_rom_source_path=/home/pizzag/Android
|
|
ssh_options=
|
|
```
|
|
|
|
The host manager builds SSH arguments using:
|
|
|
|
```text
|
|
server_address
|
|
user
|
|
port
|
|
ssh_options
|
|
```
|
|
|
|
SSH options can contain an identity file and other supported SSH arguments.
|
|
|
|
---
|
|
|
|
# 23. Remote Build Considerations
|
|
|
|
Remote builds require more than simply having SSH available.
|
|
|
|
The remote machine needs:
|
|
|
|
- Android build dependencies
|
|
- Git
|
|
- Repo where required
|
|
- Git LFS where required
|
|
- ROM source at the expected location
|
|
- Device/vendor/kernel source as required by the ROM
|
|
- Any external tools required by the scripts
|
|
|
|
The GUI is the management layer.
|
|
|
|
It does not automatically install every Android build dependency on a remote machine.
|
|
|
|
---
|
|
|
|
# 24. Terminal
|
|
|
|
The Terminal tab creates a VTE terminal and starts:
|
|
|
|
```text
|
|
/bin/bash
|
|
```
|
|
|
|
This is intentionally independent from the script runner.
|
|
|
|
It gives the developer a direct shell for:
|
|
|
|
```text
|
|
repo
|
|
git
|
|
lunch
|
|
m
|
|
brunch
|
|
adb
|
|
fastboot
|
|
grep
|
|
sed
|
|
python
|
|
bash
|
|
```
|
|
|
|
and other normal Android development operations.
|
|
|
|
---
|
|
|
|
# 25. Resource Monitor
|
|
|
|
The Resource Monitor launches:
|
|
|
|
```text
|
|
btop
|
|
```
|
|
|
|
when available.
|
|
|
|
If `btop` is unavailable, the script checks for:
|
|
|
|
```text
|
|
bpytop
|
|
```
|
|
|
|
This is useful during large builds because Android compilation can heavily stress CPU, memory, storage, and other system resources.
|
|
|
|
---
|
|
|
|
# 26. Tools Tab
|
|
|
|
The Tools tab currently handles application-side utility functions.
|
|
|
|
## Splash Screen
|
|
|
|
The splash selector loads available splash assets and stores the selected splash.
|
|
|
|
## Desktop Launcher Icon
|
|
|
|
The icon selector loads available launcher icon choices.
|
|
|
|
The selected icon is used when creating the application desktop launcher.
|
|
|
|
## Desktop Launcher
|
|
|
|
The launcher button invokes the launcher creation backend.
|
|
|
|
## Clean ROM
|
|
|
|
The clean button invokes the ROM cleaning action.
|
|
|
|
The clean operation itself remains script/backend driven.
|
|
|
|
---
|
|
|
|
# 27. UI Sizing Variables
|
|
|
|
UI dimensions are deliberately exposed as constants near the top of `gui.py`.
|
|
|
|
Current button width controls include:
|
|
|
|
```text
|
|
SYNC_SETUP_BUTTON_WIDTH
|
|
SYNC_GAPPS_BUTTON_WIDTH
|
|
BUILD_ROM_BUTTON_WIDTH
|
|
LAUNCHER_BUTTON_WIDTH
|
|
CLEAN_BUTTON_WIDTH
|
|
```
|
|
|
|
This means button widths can be adjusted without hunting through individual GTK layout blocks.
|
|
|
|
Other UI spacing controls include:
|
|
|
|
```text
|
|
BUILD_SETUP_TOP_SPACING
|
|
PROJECT_PROFILES_TOP_SPACING
|
|
SYNC_SETUP_TOP_SPACING
|
|
```
|
|
|
|
These provide independent control over vertical spacing in the corresponding UI sections.
|
|
|
|
This pattern should be followed when adding future UI dimensions.
|
|
|
|
Instead of hard-coding:
|
|
|
|
```python
|
|
button.set_size_request(140, -1)
|
|
```
|
|
|
|
prefer:
|
|
|
|
```python
|
|
button.set_size_request(
|
|
BUILD_ROM_BUTTON_WIDTH,
|
|
-1
|
|
)
|
|
```
|
|
|
|
This keeps layout tuning centralized.
|
|
|
|
---
|
|
|
|
# 28. Updater Architecture
|
|
|
|
Updater functionality is split between:
|
|
|
|
```text
|
|
builder/updater.py
|
|
builder/updater_overlay.py
|
|
scripts/updater.sh
|
|
```
|
|
|
|
The shell updater emits machine-readable progress messages.
|
|
|
|
For example:
|
|
|
|
```text
|
|
::PROGRESS::1::5
|
|
::STATUS::Downloading Update ...
|
|
```
|
|
|
|
The current updater stages are:
|
|
|
|
```text
|
|
1/5 Downloading Update
|
|
2/5 Extracting Update
|
|
3/5 Backing Up Current Installation
|
|
4/5 Installing Update
|
|
5/5 Update Installed Successfully
|
|
```
|
|
|
|
The GTK overlay consumes these messages and advances its progress bar.
|
|
|
|
This is preferable to guessing progress from arbitrary terminal output.
|
|
|
|
---
|
|
|
|
# 29. Adding a New ROM
|
|
|
|
A ROM does not normally require a new Python module.
|
|
|
|
The typical process is:
|
|
|
|
1. Create or sync the ROM source tree.
|
|
2. Select the ROM source directory in the GUI.
|
|
3. Add or select the appropriate ROM configuration.
|
|
4. Define required variables in `rom.conf`.
|
|
5. Add a build command entry if desired.
|
|
6. Ensure `scripts/build.sh` understands the resulting environment.
|
|
7. Add any ROM-specific sync/build scripts where needed.
|
|
|
|
If the ROM should carry its own settings, place:
|
|
|
|
```text
|
|
rom.conf
|
|
```
|
|
|
|
at the ROM root.
|
|
|
|
This is especially useful when multiple ROM trees have different:
|
|
|
|
- build commands
|
|
- manifest information
|
|
- branch naming
|
|
- vendor names
|
|
- output locations
|
|
- release naming
|
|
- version values
|
|
|
|
---
|
|
|
|
# 30. Recommended Device Addition Workflow
|
|
|
|
When adding a device, use this order:
|
|
|
|
### Step 1 — Device config
|
|
|
|
Create:
|
|
|
|
```text
|
|
configs/devices/<codename>.conf
|
|
```
|
|
|
|
### Step 2 — Device identity
|
|
|
|
Define:
|
|
|
|
```text
|
|
DEVICE_CODENAME
|
|
DEVICE_DISPLAY_CODENAME
|
|
DEVICE_DISPLAY_NAME
|
|
DEVICE_MANUFACTURER
|
|
DEVICE_MODEL_NUMBER
|
|
```
|
|
|
|
### Step 3 — Device sync script
|
|
|
|
Create:
|
|
|
|
```text
|
|
scripts/devices_sync/<codename>-sync.sh
|
|
```
|
|
|
|
### Step 4 — Connect the two
|
|
|
|
Set:
|
|
|
|
```text
|
|
DEVICE_SYNC_SCRIPT="<codename>-sync.sh"
|
|
```
|
|
|
|
### Step 5 — Add device-specific variables
|
|
|
|
Add only the values actually required by the device's scripts.
|
|
|
|
### Step 6 — Test the sync script directly
|
|
|
|
Before debugging the GUI, test the shell script with the required environment.
|
|
|
|
### Step 7 — Launch the GUI
|
|
|
|
The device should automatically appear in the device selector because discovery scans `configs/devices/*.conf`.
|
|
|
|
---
|
|
|
|
# 31. Adding a New Build Command
|
|
|
|
Edit:
|
|
|
|
```text
|
|
configs/rom_build_commands.conf
|
|
```
|
|
|
|
Add a simple entry:
|
|
|
|
```text
|
|
Lineage
|
|
```
|
|
|
|
or:
|
|
|
|
```text
|
|
Derpfest
|
|
```
|
|
|
|
The current GUI turns normal entries into a lowercase command value.
|
|
|
|
If a display-only/configuration entry is desired:
|
|
|
|
```text
|
|
Default --> Rom.conf
|
|
```
|
|
|
|
can be used.
|
|
|
|
After changing this file, restart the application so the Build tab reloads the list.
|
|
|
|
---
|
|
|
|
# 32. Adding a New Build Variable
|
|
|
|
If a script needs another value, first determine where the value belongs.
|
|
|
|
### Device-specific
|
|
|
|
Put it in:
|
|
|
|
```text
|
|
configs/devices/<device>.conf
|
|
```
|
|
|
|
### ROM-specific
|
|
|
|
Put it in:
|
|
|
|
```text
|
|
configs/rom.conf
|
|
```
|
|
|
|
or preferably the ROM-local:
|
|
|
|
```text
|
|
<ROM_ROOT>/rom.conf
|
|
```
|
|
|
|
when the value belongs only to that ROM.
|
|
|
|
### A-Team-wide setup
|
|
|
|
Put it in:
|
|
|
|
```text
|
|
configs/a_team_setup.conf
|
|
```
|
|
|
|
### Upload-specific
|
|
|
|
Put it in:
|
|
|
|
```text
|
|
configs/upload_services.conf
|
|
```
|
|
|
|
Then consume it from Bash:
|
|
|
|
```bash
|
|
echo "$MY_VARIABLE"
|
|
```
|
|
|
|
Avoid modifying Python simply to introduce a variable that is naturally a configuration value.
|
|
|
|
---
|
|
|
|
# 33. Debugging Configuration
|
|
|
|
If a configuration value appears to be missing, check in this order:
|
|
|
|
1. Is the file present?
|
|
2. Is the filename correct?
|
|
3. Is the filename case correct?
|
|
4. Does the line contain `=`?
|
|
5. Is the variable name spelled correctly?
|
|
6. Is the selected device correct?
|
|
7. Does the selected ROM contain its own `rom.conf`?
|
|
8. If it does, is that local file overriding `configs/rom.conf`?
|
|
9. Does the variable reference another variable that exists?
|
|
10. Does the script receive the environment being expected?
|
|
|
|
The `Project.debug_dump()` helper can be useful when inspecting project state.
|
|
|
|
---
|
|
|
|
# 34. Debugging the Script Layer
|
|
|
|
Because the project is script-driven, a useful debugging technique is to run the underlying script manually.
|
|
|
|
For example:
|
|
|
|
```bash
|
|
cd /path/to/A-Team-Android_ROM_Builder
|
|
bash scripts/sync.sh
|
|
```
|
|
|
|
or:
|
|
|
|
```bash
|
|
bash scripts/build.sh
|
|
```
|
|
|
|
with the required environment exported.
|
|
|
|
This isolates Android build problems from GTK problems.
|
|
|
|
If the script fails directly, changing the GUI usually will not fix the underlying ROM build problem.
|
|
|
|
---
|
|
|
|
# 35. Debugging the GUI
|
|
|
|
When modifying `gui.py`, test in layers.
|
|
|
|
### Syntax
|
|
|
|
```bash
|
|
python3 -m py_compile gui.py
|
|
```
|
|
|
|
### Startup
|
|
|
|
```bash
|
|
python3 gui.py
|
|
```
|
|
|
|
### UI construction
|
|
|
|
Verify that all tabs initialize:
|
|
|
|
```text
|
|
Build Setup
|
|
Sync & Setup Device Source
|
|
Build
|
|
Terminal
|
|
Resource Monitor
|
|
Tools
|
|
```
|
|
|
|
### Action testing
|
|
|
|
Exercise the changed button or dropdown rather than stopping after startup.
|
|
|
|
This is particularly important for GTK code because a valid Python file can still fail during widget construction.
|
|
|
|
---
|
|
|
|
# 36. Adding a New GUI Control
|
|
|
|
The preferred pattern is:
|
|
|
|
1. Add a constant near the other UI constants.
|
|
2. Create the widget.
|
|
3. Apply the constant.
|
|
4. Connect the signal.
|
|
5. Implement the callback.
|
|
6. Keep actual work in the backend/action/script layer.
|
|
|
|
Example:
|
|
|
|
```python
|
|
MY_BUTTON_WIDTH = 140
|
|
```
|
|
|
|
Then:
|
|
|
|
```python
|
|
self.my_button = Gtk.Button(
|
|
label="My Action"
|
|
)
|
|
|
|
set_button_width(
|
|
self.my_button,
|
|
MY_BUTTON_WIDTH
|
|
)
|
|
|
|
self.my_button.connect(
|
|
"clicked",
|
|
self.my_action_clicked
|
|
)
|
|
```
|
|
|
|
This is preferable to embedding a large shell workflow directly inside a GTK callback.
|
|
|
|
---
|
|
|
|
# 37. Why Scripts Should Stay Separate
|
|
|
|
Android ROM build operations frequently become device- and ROM-specific.
|
|
|
|
Keeping the logic in:
|
|
|
|
```text
|
|
scripts/
|
|
```
|
|
|
|
allows:
|
|
|
|
- shell testing without GTK
|
|
- easier debugging
|
|
- device-specific scripts
|
|
- ROM-specific behavior
|
|
- reuse outside the GUI
|
|
- simpler Python code
|
|
- easier migration between machines
|
|
|
|
The GUI should primarily select and prepare the environment.
|
|
|
|
---
|
|
|
|
# 38. Environment Flow Example
|
|
|
|
Suppose the user selects:
|
|
|
|
```text
|
|
Device:
|
|
Moto G Stylus 5G 2022
|
|
|
|
ROM:
|
|
Lineage
|
|
|
|
Branch:
|
|
23.2
|
|
|
|
Android:
|
|
16
|
|
|
|
Build Variant:
|
|
Userdebug
|
|
|
|
Jobs:
|
|
32
|
|
```
|
|
|
|
The project state may become conceptually:
|
|
|
|
```text
|
|
DEVICE_NAME=milanf
|
|
ROM_NAME=Lineage
|
|
ROM_BRANCH=23.2
|
|
ANDROID_VERSION=16
|
|
BUILD_VARIANT=userdebug
|
|
BUILD_JOBS=32
|
|
```
|
|
|
|
The device configuration then adds values such as:
|
|
|
|
```text
|
|
DEVICE_CODENAME=milanf
|
|
DEVICE_SOC=sm6375
|
|
DEVICE_MANUFACTURER=Motorola
|
|
```
|
|
|
|
The ROM configuration adds values such as:
|
|
|
|
```text
|
|
ROM_VENDOR_NAME=lineage
|
|
ROM_BRANCH_PREFIX=lineage-
|
|
ROM_MAJOR_VERSION=23
|
|
ROM_MINOR_VERSION=2
|
|
```
|
|
|
|
The final environment is what the scripts consume.
|
|
|
|
---
|
|
|
|
# 39. Design Principles for Future Development
|
|
|
|
When extending the project, prefer these rules:
|
|
|
|
### Keep GUI and build logic separate
|
|
|
|
Do not move large Bash workflows into GTK callbacks.
|
|
|
|
### Prefer configuration over hard-coding
|
|
|
|
If a value changes between devices or ROMs, it probably belongs in a config file.
|
|
|
|
### Prefer device configs over device conditionals
|
|
|
|
Prefer:
|
|
|
|
```text
|
|
configs/devices/milanf.conf
|
|
```
|
|
|
|
over:
|
|
|
|
```python
|
|
if device == "milanf":
|
|
...
|
|
```
|
|
|
|
### Prefer ROM-local `rom.conf` for ROM-specific behavior
|
|
|
|
This keeps a ROM's settings with its source tree.
|
|
|
|
### Keep reusable UI dimensions centralized
|
|
|
|
Add constants rather than hard-coding sizes in multiple places.
|
|
|
|
### Test the actual UI
|
|
|
|
Python syntax validation is not sufficient for GTK changes.
|
|
|
|
### Test scripts independently
|
|
|
|
A failing Android build script should be debugged as a script before changing GUI code.
|
|
|
|
---
|
|
|
|
# 40. Common Failure Areas
|
|
|
|
## Device does not appear
|
|
|
|
Check:
|
|
|
|
```text
|
|
configs/devices/
|
|
```
|
|
|
|
and make sure the file ends in:
|
|
|
|
```text
|
|
.conf
|
|
```
|
|
|
|
Also verify that it is not named one of the configuration files intentionally ignored by the device scanner.
|
|
|
|
## ROM settings seem wrong
|
|
|
|
Check whether:
|
|
|
|
```text
|
|
<ROM_ROOT>/rom.conf
|
|
```
|
|
|
|
exists.
|
|
|
|
If it does, it overrides:
|
|
|
|
```text
|
|
configs/rom.conf
|
|
```
|
|
|
|
## Build command is missing
|
|
|
|
Check:
|
|
|
|
```text
|
|
configs/rom_build_commands.conf
|
|
```
|
|
|
|
and restart the application.
|
|
|
|
## Device sync script is missing
|
|
|
|
Check:
|
|
|
|
```text
|
|
DEVICE_SYNC_SCRIPT
|
|
```
|
|
|
|
and verify:
|
|
|
|
```text
|
|
scripts/devices_sync/<script>
|
|
```
|
|
|
|
exists.
|
|
|
|
## Remote host does not appear
|
|
|
|
The host loader only exposes the Local host or SSH host entries with a non-empty:
|
|
|
|
```text
|
|
server_address
|
|
```
|
|
|
|
## Resource monitor does not start
|
|
|
|
Install:
|
|
|
|
```text
|
|
btop
|
|
```
|
|
|
|
or:
|
|
|
|
```text
|
|
bpytop
|
|
```
|
|
|
|
## GApps sync fails
|
|
|
|
Check:
|
|
|
|
- Android version
|
|
- Git
|
|
- Git LFS
|
|
- network access
|
|
- destination ROM path
|
|
|
|
---
|
|
|
|
# 41. Extending the Architecture
|
|
|
|
The project is suitable for adding additional managers.
|
|
|
|
A future feature should generally follow this structure:
|
|
|
|
```text
|
|
GUI
|
|
|
|
|
+--> Backend module
|
|
|
|
|
+--> Project/config data
|
|
|
|
|
+--> Action
|
|
|
|
|
+--> Script
|
|
```
|
|
|
|
For example, a future kernel configuration feature could be:
|
|
|
|
```text
|
|
gui.py
|
|
|
|
|
builder/kernel_manager.py
|
|
|
|
|
scripts/kernel_setup.sh
|
|
```
|
|
|
|
rather than placing the entire kernel setup implementation inside `gui.py`.
|
|
|
|
---
|
|
|
|
# 42. Current Configuration Files
|
|
|
|
The current project contains:
|
|
|
|
```text
|
|
configs/
|
|
├── a_team_setup.conf
|
|
├── devices/
|
|
│ ├── avatrn.conf
|
|
│ ├── fogo.conf
|
|
│ ├── fogos-1.conf
|
|
│ ├── fogos-2.conf
|
|
│ ├── genevn.conf
|
|
│ ├── milanf.conf
|
|
│ ├── mona.conf
|
|
│ ├── rtwo-1.conf
|
|
│ ├── rtwo-2.conf
|
|
│ └── rtwo-3.conf
|
|
├── hosts.conf
|
|
├── rom.conf
|
|
├── rom_build_commands.conf
|
|
└── upload_services.conf
|
|
```
|
|
|
|
This demonstrates the intended extensibility of the configuration system.
|
|
|
|
---
|
|
|
|
# 43. Current Script Categories
|
|
|
|
The script layer contains functionality for:
|
|
|
|
```text
|
|
Build
|
|
Clean
|
|
Device Sync
|
|
A-Team Setup
|
|
GApps Sync
|
|
Updater
|
|
Resource Monitoring
|
|
Uploading
|
|
```
|
|
|
|
Device-specific synchronization scripts live separately under:
|
|
|
|
```text
|
|
scripts/devices_sync/
|
|
```
|
|
|
|
This allows the common synchronization flow to remain stable while individual devices can have different setup requirements.
|
|
|
|
---
|
|
|
|
# 44. Updater Progress Protocol
|
|
|
|
Updater status is communicated using dedicated lines.
|
|
|
|
Status:
|
|
|
|
```text
|
|
::STATUS::Some Status Text
|
|
```
|
|
|
|
Progress:
|
|
|
|
```text
|
|
::PROGRESS::<current>::<total>
|
|
```
|
|
|
|
For example:
|
|
|
|
```text
|
|
::PROGRESS::3::5
|
|
::STATUS::Backing Up Current Installation ...
|
|
```
|
|
|
|
The GUI recognizes these messages and updates the updater overlay.
|
|
|
|
If future updater stages are added, keep this protocol stable.
|
|
|
|
---
|
|
|
|
# 45. Safe Extension Pattern for Scripts
|
|
|
|
When adding a script:
|
|
|
|
1. Put it under `scripts/`.
|
|
2. Make it executable where appropriate.
|
|
3. Validate required environment variables.
|
|
4. Fail with a non-zero exit code when an operation fails.
|
|
5. Print useful progress information.
|
|
6. Avoid assuming a specific ROM unless the script is intentionally ROM-specific.
|
|
7. Use `$ROM_PATH` rather than hard-coded source paths.
|
|
8. Use device configuration variables instead of duplicating device-specific values.
|
|
|
|
---
|
|
|
|
# 46. Summary
|
|
|
|
A-Team Android ROM Builder is best understood as a **project orchestration layer for Android ROM development**.
|
|
|
|
The most important concepts are:
|
|
|
|
```text
|
|
Device config
|
|
+
|
|
ROM config
|
|
+
|
|
GUI project selections
|
|
|
|
|
v
|
|
Project environment
|
|
|
|
|
v
|
|
Bash scripts
|
|
|
|
|
v
|
|
Android ROM source tree
|
|
```
|
|
|
|
The configuration-driven design means developers can add devices, ROMs, build commands, variables, scripts, and hosts without continuously modifying the core GUI.
|
|
|
|
For new development, preserve that separation.
|
|
|
|
The GUI should remain the control surface.
|
|
|
|
The `builder/` package should manage application state and actions.
|
|
|
|
The `configs/` directory should describe the environment.
|
|
|
|
The `scripts/` directory should perform the actual ROM-development work.
|
|
|
|
The ROM-local `rom.conf` mechanism should be used whenever a ROM needs to carry its own build configuration independently of the application-wide default.
|