update docs
This commit is contained in:
92
README.md
92
README.md
@@ -4,7 +4,41 @@ Android app for mounting ISO/IMG files as USB mass storage or CD-ROM devices on
|
|||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
Screenshots are available in the [docs/screenshots/](docs/screenshots/) directory.
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td align="center">
|
||||||
|
<img src="docs/screenshots/list_images_home.jpg" width="250px" alt="File Browser"/>
|
||||||
|
<br />
|
||||||
|
<b>File Browser with OS Icons</b>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<img src="docs/screenshots/mounted_status_home.jpg" width="250px" alt="Mounted Status"/>
|
||||||
|
<br />
|
||||||
|
<b>Mounted Status</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center">
|
||||||
|
<img src="docs/screenshots/mount_options_dialogbox.jpg" width="250px" alt="Mount Options"/>
|
||||||
|
<br />
|
||||||
|
<b>Mount Options Dialog</b>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<img src="docs/screenshots/create_img_digalogbox.jpg" width="250px" alt="Create IMG"/>
|
||||||
|
<br />
|
||||||
|
<b>Create IMG Dialog</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center">
|
||||||
|
<img src="docs/screenshots/list_listing_download.jpg" width="250px" alt="Download ISOs"/>
|
||||||
|
<br />
|
||||||
|
<b>Download OS ISOs</b>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@@ -12,7 +46,6 @@ Screenshots are available in the [docs/screenshots/](docs/screenshots/) director
|
|||||||
- Create blank IMG files for writable USB drives
|
- Create blank IMG files for writable USB drives
|
||||||
- Read-only or read-write mount options
|
- Read-only or read-write mount options
|
||||||
- Persistent notification with quick unmount button
|
- Persistent notification with quick unmount button
|
||||||
- Browse and select ISO/IMG files from device storage
|
|
||||||
- OS-specific icons for popular distributions (Linux, BSD, etc.)
|
- OS-specific icons for popular distributions (Linux, BSD, etc.)
|
||||||
- Download links to popular operating systems (Linux, BSD, Windows, Recovery tools)
|
- Download links to popular operating systems (Linux, BSD, Windows, Recovery tools)
|
||||||
- Rename and delete files
|
- Rename and delete files
|
||||||
@@ -24,44 +57,19 @@ Screenshots are available in the [docs/screenshots/](docs/screenshots/) director
|
|||||||
- USB gadget support (configfs or sysfs)
|
- USB gadget support (configfs or sysfs)
|
||||||
- Android 8.0+ (API 26)
|
- Android 8.0+ (API 26)
|
||||||
|
|
||||||
|
## Download
|
||||||
|
|
||||||
|
- **F-Droid**: *Coming soon*
|
||||||
|
- **Gitea Releases**: [Download latest APK](https://git.sargit.com/sargit/ISODroid/releases)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
### Option 1: Install APK (Recommended)
|
1. Download the APK from the links above
|
||||||
1. Download the latest ISO Droid APK from releases
|
2. Install the APK on your rooted Android device
|
||||||
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
|
|
||||||
3. Grant root access when prompted
|
3. Grant root access when prompted
|
||||||
4. Place your ISO/IMG files in `/sdcard/isodrive/` (or configure a different directory in settings)
|
4. Place your ISO/IMG files in `/sdcard/isodrive/` (or configure a different directory in settings)
|
||||||
|
|
||||||
## Building from Source
|
> **Note**: The app includes a bundled `isodrive` binary. No additional setup required!
|
||||||
|
|
||||||
### 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
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
## 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
|
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.)
|
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
|
## Credits
|
||||||
|
|
||||||
- [isodrive](https://github.com/nitanmarcel/isodrive) by nitanmarcel - The CLI tool that powers ISO Droid
|
- [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
|
- [ISODriveUT](https://github.com/fredldotme/ISODriveUT) by fredldotme - Original inspiration for isodrive
|
||||||
- OS icons from [Simple Icons](https://simpleicons.org/)
|
- 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
|
## License
|
||||||
|
|
||||||
MIT
|
GNU General Public License v3.0 - See [LICENSE](LICENSE) file for details
|
||||||
|
|||||||
333
docs/BUILDING.md
Normal file
333
docs/BUILDING.md
Normal 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
|
||||||
Reference in New Issue
Block a user