From ef5f7b4b58c171fcabbba17ea724de687eee7897 Mon Sep 17 00:00:00 2001 From: Shihaam Abdul Rahman Date: Tue, 10 Mar 2026 14:43:33 +0500 Subject: [PATCH] update docs --- README.md | 92 ++++++------- docs/BUILDING.md | 333 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 381 insertions(+), 44 deletions(-) create mode 100644 docs/BUILDING.md diff --git a/README.md b/README.md index c069ccf..2b1a7bc 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,41 @@ Android app for mounting ISO/IMG files as USB mass storage or CD-ROM devices on ## Screenshots -Screenshots are available in the [docs/screenshots/](docs/screenshots/) directory. + + + + + + + + + + + + + +
+ File Browser +
+ File Browser with OS Icons +
+ Mounted Status +
+ Mounted Status +
+ Mount Options +
+ Mount Options Dialog +
+ Create IMG +
+ Create IMG Dialog +
+ Download ISOs +
+ Download OS ISOs +
+
## Features @@ -12,7 +46,6 @@ Screenshots are available in the [docs/screenshots/](docs/screenshots/) director - Create blank IMG files for writable USB drives - Read-only or read-write mount options - Persistent notification with quick unmount button -- Browse and select ISO/IMG files from device storage - OS-specific icons for popular distributions (Linux, BSD, etc.) - Download links to popular operating systems (Linux, BSD, Windows, Recovery tools) - Rename and delete files @@ -24,44 +57,19 @@ Screenshots are available in the [docs/screenshots/](docs/screenshots/) director - USB gadget support (configfs or sysfs) - Android 8.0+ (API 26) +## Download + +- **F-Droid**: *Coming soon* +- **Gitea Releases**: [Download latest APK](https://git.sargit.com/sargit/ISODroid/releases) + ## Installation -### Option 1: Install APK (Recommended) -1. Download the latest ISO Droid APK from releases -2. Install the APK -3. Grant root access when prompted -4. The app includes a bundled isodrive binary -5. Place your ISO/IMG files in `/sdcard/isodrive/` (or configure a different directory in settings) - -### Option 2: Install with Magisk Module -1. Install the [isodrive Magisk module](https://github.com/nitanmarcel/isodrive-magisk/releases/latest) -2. Install the ISO Droid APK +1. Download the APK from the links above +2. Install the APK on your rooted Android device 3. Grant root access when prompted 4. Place your ISO/IMG files in `/sdcard/isodrive/` (or configure a different directory in settings) -## Building from Source - -### Prerequisites - -Before building the app, you need to obtain the `isodrive` binary: - -1. The `isodrive` binary is compiled from [nitanmarcel/isodrive](https://github.com/nitanmarcel/isodrive) -2. Place the compiled binary at `app/src/main/assets/bin/isodrive` before building -3. The binary must be executable and compiled for the appropriate Android architecture - -### Build Steps - -```bash -# Clone the repository -git clone https://github.com/yourusername/ISODroid.git -cd ISODroid - -# Ensure isodrive binary is present -ls -la app/src/main/assets/bin/isodrive - -# Build the APK -./gradlew assembleRelease -``` +> **Note**: The app includes a bundled `isodrive` binary. No additional setup required! ## Usage @@ -79,20 +87,16 @@ ls -la app/src/main/assets/bin/isodrive 3. The app will create a blank IMG file that can be mounted as a writable USB drive 4. Format it on your PC after mounting (FAT32, exFAT, NTFS, etc.) +## Documentation + +- **[Building & Technical Details](docs/BUILDING.md)** - How to build from source, architecture overview, and technical documentation + ## Credits - [isodrive](https://github.com/nitanmarcel/isodrive) by nitanmarcel - The CLI tool that powers ISO Droid - [ISODriveUT](https://github.com/fredldotme/ISODriveUT) by fredldotme - Original inspiration for isodrive - OS icons from [Simple Icons](https://simpleicons.org/) -## Technical Details - -ISO Droid uses the `isodrive` binary to interface with the Linux USB gadget subsystem. The app: -- Bundles the isodrive binary in `app/src/main/assets/bin/` -- Extracts and executes it with root permissions at runtime -- Supports both configfs (modern) and sysfs (legacy) USB gadget modes -- Dynamically detects available OS icons for file display - ## License -MIT +GNU General Public License v3.0 - See [LICENSE](LICENSE) file for details diff --git a/docs/BUILDING.md b/docs/BUILDING.md new file mode 100644 index 0000000..4672da2 --- /dev/null +++ b/docs/BUILDING.md @@ -0,0 +1,333 @@ +# Building ISO Droid + +This document contains technical information for building and understanding ISO Droid. + +## Building from Source + +### Prerequisites + +Before building the app, you need to obtain the `isodrive` binary: + +1. The `isodrive` binary is compiled from [nitanmarcel/isodrive](https://github.com/nitanmarcel/isodrive) +2. Place the compiled binary at `app/src/main/assets/bin/isodrive` before building +3. The binary must be executable and compiled for the appropriate Android architecture (ARM64 recommended for modern devices) + +### Build Steps + +```bash +# Clone the repository +git clone https://github.com/sargit/ISODroid.git +cd ISODroid + +# Ensure isodrive binary is present +ls -la app/src/main/assets/bin/isodrive + +# Build the debug APK +./gradlew assembleDebug + +# Or build the release APK (requires signing configuration) +./gradlew assembleRelease +``` + +The compiled APK will be located at: +- Debug: `app/build/outputs/apk/debug/app-debug.apk` +- Release: `app/build/outputs/apk/release/app-release.apk` + +## Technical Architecture + +### Overview + +ISO Droid is built using modern Android development practices: +- **Language**: Kotlin +- **UI Framework**: Jetpack Compose (Material 3) +- **Architecture**: MVVM (Model-View-ViewModel) +- **Minimum SDK**: 26 (Android 8.0) +- **Target SDK**: 34 (Android 14) + +### Core Components + +#### 1. IsoDriveManager (`isodrive/IsoDriveManager.kt`) + +The central component that interfaces with the `isodrive` binary: + +- **Binary Extraction**: Copies the bundled `isodrive` binary from assets to app-specific storage +- **Permission Management**: Ensures the binary has executable permissions (`chmod 755`) +- **Command Execution**: Wraps all isodrive commands (mount, unmount, status checks) +- **Device Support Detection**: Checks for configfs or sysfs USB gadget support + +```kotlin +// Example: Mounting an ISO +isoDriveManager.mount( + filePath = "/sdcard/isodrive/ubuntu.iso", + mountType = MountType.CDROM, + readOnly = true +) +``` + +#### 2. RootManager (`root/RootManager.kt`) + +Handles all root access operations: + +- **Root Detection**: Checks for available root methods (Magisk, KernelSU, APatch, su binary) +- **Cached Status**: Stores root grant status to avoid repeated prompts +- **Command Execution**: Executes shell commands with root privileges +- **Error Handling**: Captures stdout, stderr, and exit codes + +```kotlin +val result = RootManager.executeCommand("isodrive status") +if (result.isSuccess) { + // Parse output +} +``` + +#### 3. USB Gadget Subsystem + +ISO Droid supports both modern and legacy USB gadget interfaces: + +**ConfigFS (Modern - Preferred)** +- Path: `/config/usb_gadget/` +- More flexible and feature-rich +- Standard on Android 8.0+ devices + +**SysFS (Legacy)** +- Path: `/sys/class/android_usb/` +- Older interface +- Fallback for older devices + +The `isodrive` binary automatically detects and uses the appropriate interface. + +#### 4. Mount Types + +**Mass Storage Mode** +- Exposes the file as a USB mass storage device +- Supports read-write mode for IMG files +- Host PC sees it as a USB flash drive +- Can be formatted with any filesystem (FAT32, NTFS, exFAT, ext4) + +**CD-ROM Mode** +- Exposes the file as a virtual CD/DVD drive +- Always read-only +- Ideal for bootable ISOs +- Host PC sees it as an optical drive + +### UI Architecture + +#### Jetpack Compose + +All UI is built using Jetpack Compose with Material 3: + +- **Declarative**: UI is a function of state +- **Reactive**: Automatically updates when state changes +- **Type-safe**: Compile-time checking for UI code + +#### Key Screens + +1. **MainScreen** (`ui/screens/MainScreen.kt`) + - File browser with OS icon detection + - Mount/unmount operations + - Status card showing current mount state + +2. **DownloadsScreen** (`ui/screens/DownloadsScreen.kt`) + - Curated list of OS download links + - Grouped by category (Linux, BSD, Windows, Recovery) + +3. **SettingsScreen** (`ui/screens/SettingsScreen.kt`) + - Root permission status + - Notification permission (Android 13+) + - Default ISO directory configuration + - App version and build information + +#### State Management + +Uses Kotlin StateFlow for reactive state: + +```kotlin +data class MainUiState( + val isLoading: Boolean = true, + val hasRoot: Boolean? = null, + val isSupported: Boolean? = null, + val mountStatus: MountStatus = MountStatus.UNMOUNTED, + val isoFiles: List = emptyList(), + // ... +) +``` + +### OS Icon Detection + +Dynamic icon matching system: + +1. **Icon Storage**: SVG files in `app/src/main/assets/osicons/` +2. **Dynamic Loading**: Icons are loaded at runtime via `AssetManager` +3. **Fuzzy Matching**: Filename matching algorithm: + - Converts filename to lowercase + - Checks for icon name presence (e.g., "ubuntu" in "ubuntu-22.04-desktop.iso") + - Prioritizes longer matches (e.g., "linuxmint" over "linux") + - Prefers earlier position in filename + +4. **Rendering**: Uses Coil image library with SVG decoder +5. **Badge System**: Small circular badge shows file type (ISO/IMG) + +### File Operations + +#### Creating IMG Files + +```kotlin +// User specifies size (e.g., 4 GB) +val sizeBytes = 4L * 1024 * 1024 * 1024 + +// Creates sparse file using dd with progress reporting +dd if=/dev/zero of=/sdcard/isodrive/custom.img bs=1M count=4096 + +// Progress events are emitted via CreateImgEventBus +``` + +#### Rename/Delete Protection + +- Files currently mounted cannot be renamed or deleted +- UI shows warning message and disables actions +- Prevents accidental data corruption + +### Notifications + +Persistent notification while mounted: + +- **Information**: Shows mounted filename and mount type +- **Quick Actions**: Unmount button in notification +- **Foreground Service**: Ensures notification stays visible +- **Auto-dismiss**: Notification removed after unmount + +### Data Persistence + +Uses Android DataStore (Preferences): + +```kotlin +// Saves user preferences +dataStore.edit { preferences -> + preferences[KEY_ISO_DIRECTORY] = "/sdcard/custom/path" +} +``` + +Stores: +- ISO directory path +- Root grant status (from setup wizard) +- App settings + +### Event Bus System + +Decoupled communication using Kotlin Flow: + +```kotlin +// Mount events +object MountEventBus { + private val _events = MutableSharedFlow() + val events: SharedFlow = _events.asSharedFlow() +} + +// Emit event from notification +MountEventBus.emit(MountEvent.Unmounted) + +// Observe in ViewModel +MountEventBus.events.collect { event -> + when (event) { + is MountEvent.Unmounted -> updateUiState() + } +} +``` + +## Dependencies + +### Core Libraries + +- **Jetpack Compose**: Modern declarative UI +- **Material 3**: Design system and components +- **Lifecycle & ViewModel**: Android Architecture Components +- **DataStore**: Modern preference storage +- **Coroutines**: Asynchronous programming + +### Image Loading + +- **Coil**: Image loading library +- **Coil SVG**: SVG decoder for OS icons + +### JSON Parsing + +- **org.json**: Parsing OS download list (`assets/os.json`) + +## Testing + +### Manual Testing Checklist + +- [ ] Root access granted on first launch +- [ ] USB gadget support detected correctly +- [ ] ISO files mount successfully +- [ ] IMG files can be created and mounted +- [ ] OS icons display correctly +- [ ] Unmount via notification works +- [ ] File rename/delete protection when mounted +- [ ] Settings persist across app restarts +- [ ] Dark mode toggles correctly + +### Device Compatibility + +Tested on: +- Modern devices with ConfigFS (Android 8.0+) +- Legacy devices with SysFS (older Android versions) +- Various root methods (Magisk, KernelSU, APatch) + +## Debugging + +### Enable Verbose Logging + +Check logcat for ISO Droid logs: + +```bash +adb logcat | grep -i "isodroid\|isodrive" +``` + +### Common Issues + +**"Device not supported"** +- Check for USB gadget support: `ls /config/usb_gadget/` or `ls /sys/class/android_usb/` +- Verify kernel has USB gadget drivers + +**"Root access required"** +- Ensure root manager (Magisk/KernelSU) is installed +- Grant root access when prompted +- Check `RootManager.hasRoot()` returns true + +**Mount fails** +- Verify file exists and is readable +- Check file isn't corrupted +- Ensure no other USB modes are active +- Try rebooting device + +### isodrive Binary Version + +Check the bundled binary version: + +```bash +adb shell +su +/data/data/sh.sar.isodroid/files/isodrive --version +``` + +## Contributing + +### Code Style + +- Follow Kotlin coding conventions +- Use meaningful variable names +- Comment complex logic +- Keep functions focused and small + +### Pull Requests + +1. Fork the repository +2. Create a feature branch +3. Make your changes +4. Test thoroughly on a real device +5. Submit a pull request with description + +## License + +GNU General Public License v3.0 - See [LICENSE](../LICENSE) file for details