update docs

This commit is contained in:
2026-03-10 14:43:33 +05:00
parent 8a594618ef
commit ef5f7b4b58
2 changed files with 381 additions and 44 deletions

333
docs/BUILDING.md Normal file
View File

@@ -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<IsoFile> = 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<MountEvent>()
val events: SharedFlow<MountEvent> = _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