Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 120 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,33 +23,133 @@ This project is under GPLv3 license.
If you see a bug or an enhanceable point, feel free to create an issue, so that we can discuss about it, and once approved, we or you (depending on the priority of the bug/improvement) will take care of the issue and apply a merge request.
Please, don't do a merge request before creating an issue.

## Tech things
## Architecture

### Overview

The kDrive Android application follows a **modular architecture** designed for maintainability, testability, and scalability. The project is organized into multiple Gradle modules with clear separation of concerns.

```
android-kDrive/
├── app/ # Main application module
│ └── src/main/java/com/infomaniak/drive/
│ ├── data/ # Data layer (API, cache, models)
│ │ ├── api/ # API clients and endpoints (Ktor)
│ │ ├── cache/ # Realm database configuration
│ │ ├── models/ # Data models (File, Drive, User, etc.)
│ │ ├── sync/ # Background synchronization
│ │ └── services/ # Background services
│ ├── ui/ # Presentation layer (MVVM)
│ │ ├── fileList/ # File browsing and management
│ │ ├── menu/ # Navigation drawer menus
│ │ ├── login/ # Authentication flows
│ │ ├── home/ # Home screen
│ │ └── ...
│ ├── di/ # Dependency injection (Hilt)
│ ├── utils/ # Utility classes
│ └── extensions/ # Kotlin extensions
└── Core/ # Infomaniak Core libraries (composite build)
├── Legacy/ # Legacy core module
├── Legacy/AppLock/ # App lock functionality
└── Legacy/BugTracker/ # Bug tracking integration
```

### Architecture Pattern

The app follows the **MVVM (Model-View-ViewModel)** architecture pattern:

- **Model**: Data classes and repositories handling data operations
- **View**: Activities, Fragments, and Composables observing ViewModel state
- **ViewModel**: Business logic and state management using LiveData/StateFlow

### Data Flow

```
UI Layer (Activities/Fragments/Composables)
ViewModel Layer (StateFlow/LiveData)
Repository Layer (Data operations)
Data Layer (API/Local Storage)
├── API (Ktor client)
├── Realm (Offline data)
└── Room (Auth tokens)
```

## Tech Stack

### Languages
Layouts were made in **XML** with Android "Layout" components, the whole project is developed in **Kotlin**.
- **Kotlin** - Primary language (100%)
- **XML** - Legacy UI layouts (migrating to Compose)

### UI Framework
- **Jetpack Compose** - Modern declarative UI (migration in progress)
- **XML Layouts** - Legacy views (gradually being replaced)
- **Material Design 3** - UI components and theming

### Architecture Components
- **Hilt** - Dependency injection
- **Navigation Component** - In-app navigation with Safe Args
- **ViewModel** - UI-related data management
- **WorkManager** - Background work scheduling

### Compatibility
The minimum needed version to execute the app is Android Lollipop 5.1 (API 22), anyway, we recommend to use the most recent version of Android, the majority of our tests having been carried out on Android 10 & 11 (API 29 & 30).
### Networking & Data
- **Ktor Client** - HTTP client for API communication
- **Realm** - NoSQL database for offline file data
- **Room** - SQL database for authentication tokens
- **DataStore** - Key-value storage for preferences

### Cache
We use [Realm.io](https://realm.io/) on both platforms (iOS and Android) to store the offline data of files, shares, app and user preferences (in different databases instances). [Android Room](https://developer.android.com/training/data-storage/room) is used to store API access token and basic user data.
### Build System
- **Gradle Kotlin DSL** - Build configuration
- **Version Catalogs** - Centralized dependency management
- **Composite Builds** - Core libraries as included builds

### Structure
The structure of the app, its algorithms and the general functioning are common with the iOS app.
## Build Flavors

The project supports multiple build flavors for different distribution channels:

| Flavor | Description | Features |
|--------|-------------|----------|
| **standard** | Google Play Store version | Firebase Cloud Messaging, Google Play Services |
| **fdroid** | F-Droid version | No proprietary dependencies, fully open source |
| **preprod** | Pre-production testing | Points to staging API servers |

## Compatibility

- **Minimum SDK**: Android 8.1 (API 27 - Oreo)
- **Target SDK**: Latest stable Android version
- **Recommended**: Android 10+ (API 29+) for best experience

## Cache & Storage

We use [Realm](https://realm.io/) on both platforms (iOS and Android) to store offline data including files, shares, app and user preferences (in separate database instances).

[Android Room](https://developer.android.com/training/data-storage/room) is used to store API access tokens and basic user data securely.

The sync mechanism ensures data consistency between the local cache and the server using background workers.

### Permissions
| Permission key | Usage
|---|---
| `GET_ACCOUNTS`, `AUTHENTICATE_ACCOUNTS`, `MANAGE_ACCOUNTS`, `USE_CREDENTIALS` | Used to access and manage AccountManager.
| `com.infomaniak.permission.ASK_CREDENTIAL`, `com.infomaniak.permission.RECEIVE_CREDENTIAL` | (*Unused for the moment*) Allow kDrive to communicate (get and give) credentials to other Infomaniak apps (in order to authenticate user without asking them to login).
| `INTERNET`, `ACCESS_NETWORK_STATE` | Used to determine if device has access to Internet in order to update UI and to restrict some features when offline.
| `READ_EXTERNAL_STORAGE`, `WRITE_EXTERNAL_STORAGE` | **READ** is used to access files on device to upload them on kDrive. **WRITE** is used to download files from kDrive on device and to use MediaStore.
| `READ_SYNC_SETTINGS`, `WRITE_SYNC_SETTINGS`, `READ_SYNC_STATS` | Used to manage automatic synchronization (e.g. determine if sync is enabled, enable it, etc.)
| `RECEIVE_BOOT_COMPLETED` | Determine when device is booted to restart sync service if needed.
| `FOREGROUND_SERVICE` | Used by Download Worker (for offline files) and Sync Service.
| `REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` | Allow to download files in background.
| `USE_BIOMETRIC` | Used to (un)lock the app.
| `REQUEST_INSTALL_PACKAGES` | Allow users to execute an APK from kDrive app.

| Permission | API Level | Usage |
|------------|-----------|-------|
| `INTERNET` | All | Network access for API calls and file operations |
| `READ_EXTERNAL_STORAGE` | ≤32 | Access files on device for upload (legacy) |
| `WRITE_EXTERNAL_STORAGE` | ≤32 | Download files to device (legacy) |
| `ACCESS_MEDIA_LOCATION` | 29+ | Access location metadata in media files |
| `READ_MEDIA_IMAGES` | 33+ | Access photos for upload (Android 13+) |
| `READ_MEDIA_VIDEO` | 33+ | Access videos for upload (Android 13+) |
| `READ_MEDIA_VISUAL_USER_SELECTED` | 34+ | Access user-selected photos/videos (Android 14+) |
| `FOREGROUND_SERVICE` | All | Background file sync and download |
| `FOREGROUND_SERVICE_DATA_SYNC` | 34+ | Foreground service for data synchronization |
| `RECEIVE_BOOT_COMPLETED` | All | Restart sync service after device reboot |
| `REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` | All | Allow background file downloads |
| `REQUEST_INSTALL_PACKAGES` | All | Install APK files from kDrive |
| `CAMERA` | All | Document scanning (optional, ChromeBook compatible) |
| `WAKE_LOCK` | All | Keep screen on during video playback |

**Note:** Storage permissions have been updated for Android 13+ (API 33+) with granular media permissions (`READ_MEDIA_*`) replacing the broad storage access.

## Tests

Expand Down