Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
144 commits
Select commit Hold shift + click to select a range
4b971ac
Updated gradle plugin 8.5, kotlin 1.9.22, java v17, target SDK 34
Dimowner Jan 21, 2024
19c0316
Migrated to gradle.ktx, version catalogs and ksp.
Dimowner Jan 21, 2024
dd8cd4b
Added Room database for Records with unit test coverage.
Dimowner Jan 24, 2024
2fc8729
Added ability to mark records as moved to recycle bin.
Dimowner Jan 25, 2024
dccfed3
Added Compose to the app and some test screens made with compose.
Dimowner Jan 28, 2024
ef15cc5
merge with master
Dimowner Feb 8, 2024
632a050
Compose Record info screen and Settings scree UI only.
Dimowner Feb 17, 2024
3f74462
Added new app preferences implementation PrefsV2
Dimowner Feb 25, 2024
593330b
New Settings screen written with Kotlin + Compose.
Dimowner Mar 3, 2024
89bb893
Show Records count and total Records duration.
Dimowner Mar 7, 2024
ba21836
Dynamic Recording settings UI updates. Animated Settings screen updates.
Dimowner Mar 8, 2024
fa7c035
Records list screen UI in Compose
Dimowner Mar 9, 2024
3e62304
Added FileDataSource and functions to work with files. Added RecordsD…
Dimowner Mar 10, 2024
433ea03
Import record implementation. Home screen drop down menu. Multiple fi…
Dimowner Mar 16, 2024
2601f3f
Home screen UI, Record information improvements. Store record duratio…
Dimowner Mar 17, 2024
dfe6ac9
Records screen UI. Home screen Dialogs.
Dimowner Mar 27, 2024
1b0c6e8
Update Home screen when active record changed.
Dimowner Mar 31, 2024
b16f984
Records screen implemented context menu actions. Added Rename/Delete/…
Dimowner Apr 1, 2024
8b76d51
Added more queries to Room database. Added more unit tests to Room da…
Dimowner Apr 6, 2024
33af901
Sort by (date/name/duration) records functionality. Add record to boo…
Dimowner Apr 6, 2024
e95f250
Added Welcome and Deleted records screens in Compose.
Dimowner Apr 7, 2024
1e27693
Added Welcome setup settings screen. Cleanup.
Dimowner Apr 7, 2024
f101cfd
Update UI when record deleted or restored. Improvements.
Dimowner Apr 28, 2024
20ebe4a
Move RecordsViewModel outside of the RecordsScreen to fix layout Prev…
Dimowner Apr 28, 2024
5da050d
Move SettingsViewModel outside of the SettingsScreen and WelcomeSetup…
Dimowner Apr 28, 2024
8466042
Move ViewModels outside of the Screens to fix layout Preview and impr…
Dimowner Apr 28, 2024
d66be76
Make rename/move to recycle/restore from recycle/delete safer - added…
Dimowner May 10, 2024
30f8bff
Merge with master
Dimowner Oct 13, 2024
5f23efa
Updated libraries versions
Dimowner Oct 13, 2024
89e7712
Added WaveformComposeView which is Compose equivalent of WaveformViewNew
Dimowner Nov 6, 2024
8976698
Implemented active record playback with UI updates on HomeScreen
Dimowner Nov 10, 2024
47333a5
Compose Waveform: Animate to start after stop. Don't update waveform …
Dimowner Nov 16, 2024
c399fca
Import Record Decoding. Record playback panel in the records screen.
Dimowner Dec 1, 2024
789ffae
Use Legacy Slider. Show timeline in home screen and hide it in record…
Dimowner Dec 8, 2024
74da024
Playback Panel UI, interactions and animations. Compose waveform heig…
Dimowner Dec 14, 2024
d320cac
Improved Records play panel enter and exit animations. Fixed records …
Dimowner Dec 21, 2024
66c8bd3
Added empty screen logo. Added empty logo to empty list. Fixed TouchP…
Dimowner Feb 24, 2025
7027303
Ability to switch to new app version (V2) and back to the legacy vers…
Dimowner Jun 8, 2025
410a375
Updated target SDK to 36, minSdk to 24. Updated gradlew plugin. Updat…
Dimowner Oct 11, 2025
35bd353
Fix back navigation and dark status bar icons when status bar also dark.
Dimowner Oct 18, 2025
40d81b0
Added records Multi-Select feature that allows to share/download/move…
Dimowner Oct 20, 2025
6ed72d6
Added date headers to the records list. Some cleanup.
Dimowner Oct 25, 2025
47fa433
Update Recording panel. Simple recording. Some fixes and improvements…
Dimowner Nov 23, 2025
8192240
Waveform Max amplitude 32767. Auto remove outdated records from trash…
Dimowner Dec 21, 2025
4ae36af
Waveform test data cleanup. Move to recycle improvements for one and …
Dimowner Dec 23, 2025
6a3bd5f
Libraries versions update.
Dimowner Jan 7, 2026
bcf2515
Implement runtime permission handling for audio recording
Dimowner Jan 12, 2026
ead59cf
Implement auto-split/chunking feature that starts new recording after…
Dimowner Jan 12, 2026
f9a7361
Added max recording duration setting in app settings screen that allo…
Dimowner Jan 12, 2026
bfaed0f
Replaced recording duration input field in in app settings screen by …
Dimowner Jan 12, 2026
4f84a3f
Add Bluetooth permission support foundation.
Dimowner Jan 18, 2026
28f21dc
Add AudioManagerHelper class with Bluetooth microphone support.
Dimowner Jan 18, 2026
ff5fe09
Added a new setting that allows to choose audio source for media reco…
Dimowner Jan 18, 2026
a14882e
Added a new feature that allows to select between available Bluetooth…
Dimowner Jan 18, 2026
eec97fe
Added Audio Source info dialog that provides more information about e…
Dimowner Jan 18, 2026
b996786
Add HTML formatting support for InfoAlertDialog. Update info_audio_so…
Dimowner Jan 18, 2026
65ea3d9
Removed BLUETOOTH_CONNECT permission as not needed. Removed related t…
Dimowner Jan 18, 2026
b686642
Added a Service that runs database migration from SQLiteHelper to Room.
Dimowner Jan 25, 2026
6d8736d
Added deleted record file detection. If record file deleted before th…
Dimowner Jan 29, 2026
3a2df7f
Lost records v2 feature fixes and cleanup.
Dimowner Jan 31, 2026
c149d95
Added a new foreground Audio Playback Service that survives app kill …
Dimowner Feb 8, 2026
23c69da
Import audio file todo fixes.
Dimowner Feb 8, 2026
1a7283b
Import audio file todo fixes.
Dimowner Feb 10, 2026
7c0dd31
Implemented click record name to to rename on home screen.
Dimowner Feb 10, 2026
502c144
Implemented click record name to to rename on home screen.
Dimowner Feb 10, 2026
a5fd67f
Animate play panel buttons visibility.
Dimowner Feb 11, 2026
24faaee
Make Toolbar scrollable in settings screen, deleted records screen an…
Dimowner Feb 11, 2026
c0bda24
Make scrollable info panel in deleted records screen and lost records…
Dimowner Feb 12, 2026
150e1fe
Make Toolbar scrollable in the records screen.
Dimowner Feb 14, 2026
af57e8f
Updated record save confirmation message, added record name.
Dimowner Feb 14, 2026
104fcdf
Move recording progress into a Foreground service so it can survive a…
Dimowner Feb 14, 2026
a784ca0
Recording progress in Foreground a service fixes. Moved auto slicing …
Dimowner Feb 15, 2026
bc266ca
Update decoded record in database from the DecodeService.kt to fix an…
Dimowner Feb 17, 2026
6e7b797
Fixed failing unit tests
Dimowner Feb 19, 2026
5c5da43
Updated Gradle plugin to 9.0.1. Configured jococo unit test coverage …
Dimowner Feb 20, 2026
12d86bb
Updated libraries version and Gradle to 9.3.1
Dimowner Feb 20, 2026
c91ab3a
Simplified move/restore from recycle logic. Updated and added missing…
Dimowner Feb 21, 2026
c998dd2
Include androidTest into JoCoCo test report. Added instructions on ho…
Dimowner Feb 22, 2026
0ed47a5
Improve unit test coverage. DataExtensions, FileExtensions, RecordDao…
Dimowner Feb 22, 2026
f3559e3
Added unit tests to FileDataSourceImpl and missing tests to PrefsImpl.
Dimowner Feb 22, 2026
0a4abc1
Updated Jacoco excludes list
Dimowner Feb 22, 2026
cc9cff9
Added unit tests for legacy PrefsImpl
Dimowner Feb 22, 2026
0c6d1f5
Added unit tests for RecordDataSourceTest.kt
Dimowner Feb 23, 2026
a6f9832
Added unit tests for LocalRepositoryImpl.kt
Dimowner Feb 24, 2026
fef5aab
Added unit tests for FileRepositoryImpl.kt
Dimowner Feb 27, 2026
c5d8ad4
Keep Home screen ON during recording when the setting 'Keep Screen ON…
Dimowner Feb 28, 2026
b53ec9b
Show rename dialog after recording stopped if setting askToRenameAfte…
Dimowner Feb 28, 2026
a5ebc6a
Update recording progress and recording info once per second in HomeS…
Dimowner Feb 28, 2026
ec394ae
Fixed an issue when SnackBar overlapped BottomBar menu.
Dimowner Feb 28, 2026
ee18fef
Added 3GP recorder V2. Implemented ability to switch between m4a and …
Dimowner Mar 1, 2026
6c71604
WavRecorder fixes and improvements.
Dimowner Mar 1, 2026
9380781
Added a feature that allows to set records author/artist name and rec…
Dimowner Mar 5, 2026
b51f760
Restore broken record feature. If a record in the database has durati…
Dimowner Mar 7, 2026
8bf862b
Implemented WavRecorderV2.kt to record in WAV format.
Dimowner Mar 8, 2026
0581413
Removed temp PCM file from WavRecorderV2. Now audio data recorded dir…
Dimowner Mar 8, 2026
2ad78de
Moved shared logic from AudioRecorderV2.kt and ThreeGpRecorderV2.kt t…
Dimowner Mar 8, 2026
bad8d58
Cleanup
Dimowner Mar 8, 2026
e4992b0
Restore broke Wav records feature.
Dimowner Mar 9, 2026
a2c36f9
Restore broke 3gp records feature (NB and WB).
Dimowner Mar 9, 2026
9a013f4
Stop recording(V2) and playback(V2) when the device is shutting down …
Dimowner Mar 9, 2026
771d4f9
Stop recording(V2) when device is running out of space. Recording get…
Dimowner Mar 9, 2026
a7c29cd
Updated AGP plugin from 9.0.1 to 9.1.0
Dimowner Mar 11, 2026
6b69290
Implemented recording progress visualisation on HomeScreen (V2)
Dimowner Mar 15, 2026
7f99d5e
Moved recording progress state from HomeViewModdel to AudioRecordingS…
Dimowner Mar 21, 2026
c50052e
Recording progress state update fixes in HomeViewModdel.
Dimowner Mar 24, 2026
b41a76e
Cleanup
Dimowner Mar 24, 2026
0d5a434
Fixed a desync that happened after waveform decoding completes and wa…
Dimowner Mar 24, 2026
671a91e
Fixed a multiple subscriptions issue for recording events in AudioRec…
Dimowner Mar 24, 2026
83169c8
Added record import and decoding progress UI on HomeScreen to indicat…
Dimowner Mar 24, 2026
0071911
Start WelcomeScreen on the first app start instead of WelcomeActivity.
Dimowner Mar 29, 2026
d13dc83
Added more settings to Welcome Setup Settings Screen. Added Author n…
Dimowner Mar 29, 2026
c4744d5
Added a reactive StateFlow for the dark theme preference and observe …
Dimowner Apr 5, 2026
d68e6a4
Set the system navigation bar background to the theme's surface color…
Dimowner Apr 5, 2026
161283f
Add a Spacer item at the bottom of the LazyColumn in the RecordsScree…
Dimowner Apr 5, 2026
e7bf496
Formatted bitrate information message using html to show it formatted…
Dimowner Apr 5, 2026
4b9cb30
Formatted recording format and Sample rate information message using …
Dimowner Apr 5, 2026
fd5b567
Removed ComposePlaygroundScreen.kt
Dimowner Apr 5, 2026
4bad720
Updated RecordingWidget so now it supports RecorderV2. The change add…
Dimowner Apr 5, 2026
2c82609
Added getDefaultProguardFile("proguard-android-optimize.txt") alongs…
Dimowner Apr 5, 2026
40f63fc
Fixed the App shortcut. Now when you start recording with the App sho…
Dimowner Apr 5, 2026
5cd45ec
Remove the recordName parameter from startServiceForeground and gener…
Dimowner Apr 5, 2026
d54132d
Use same shared Room database for Legacy app V1 and new app V2.
Dimowner Apr 9, 2026
cf4a217
UI adjustments for App V2
Dimowner Apr 15, 2026
845b0ce
Show available space in the App V2. Improved available space and tota…
Dimowner Apr 15, 2026
a0b88d4
Added Unit tests for LocalRepositoryRoomImpl.kt
Dimowner Apr 15, 2026
e45c917
Updated AGP plugin to 9.1.1. Added toolchains resolver using the Fooj…
Dimowner Apr 15, 2026
317f255
Clear recordedRecordId after recording stopped or error happened. Cle…
Dimowner Apr 15, 2026
9b1a546
Stop audio playback after the process is killed.
Dimowner Apr 15, 2026
40e608b
Add static waveform visualization widget and integrate into RecordInf…
Dimowner Apr 16, 2026
e17ba7c
Recording state handling fixes and refactoring for App V2.
Dimowner Apr 16, 2026
9c7673f
Fix new name dialog issues that displayed after stop recording for Ap…
Dimowner Apr 16, 2026
f2176f6
Implement file name collision checks during record renaming and updat…
Dimowner Apr 16, 2026
340f565
Added AGENTS.md for AI agents guidance.
Dimowner Apr 17, 2026
52a3890
Update trash_info strings for clarity and consistency across multiple…
Dimowner Apr 17, 2026
7d16ba8
Prevent info messages from showing during delete recording progress i…
Dimowner Apr 17, 2026
ada200c
Refactor amplitude calculation in WavRecorderV2 to use sumOfAmplitude…
Dimowner Apr 17, 2026
51aae4f
Enhance audio amplitude handling by scaling raw samples and improving…
Dimowner Apr 17, 2026
7946d26
Fix UI state reconciliation for recording and prevent stale progress …
Dimowner Apr 17, 2026
54d6177
Reset waveform data offset when stopping recording in HomeViewModel
Dimowner Apr 17, 2026
75327e9
Refactor default values to use uppercase constants and enhance 3GP bi…
Dimowner Apr 17, 2026
59be681
Fixed few bugs related to 'Can't create file error' and error snackba…
Dimowner Apr 18, 2026
ef9ccc6
Update status and navigation bar colors for Android 12+ and below
Dimowner Apr 18, 2026
84f0de3
Align waveform sample count with duration to prevent drift and improv…
Dimowner Apr 18, 2026
ddd395b
Refactor tag writing logic to use extension function on File and remo…
Dimowner Apr 26, 2026
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
97 changes: 97 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# AGENTS.md

This file provides guidance to AI coding agents working with this repository.

## Build Commands

```bash
# Build
./gradlew build

# Unit tests (debug config flavor)
./gradlew testDebugConfigDebugUnitTest

# Instrumented tests (requires connected device/emulator)
./gradlew connectedDebugConfigDebugAndroidTest

# Coverage reports
./gradlew jacocoTestReport # Unit test coverage → app/build/reports/jacoco/html/
./gradlew jacocoFullReport # Combined coverage → app/build/reports/jacoco/htmlFull/
./gradlew jacocoTestCoverageVerification # Enforce 5% line coverage minimum
```

**Build flavors:** `debugConfig` (debug, signed) and `releaseConfig` (minified/shrunk). Most tasks require the flavor in the task name (e.g., `testDebugConfigDebugUnitTest`).

## Architecture Overview

### Dual Codebase (V1 → V2 Migration in Progress)

The app contains two parallel implementations:
- **V2** (`app/src/main/java/.../v2/`) — active development target: Kotlin, Jetpack Compose, Hilt, Room, MVVM + Clean Architecture
- **V1** (`app/src/main/java/.../` root level) — legacy: Java, Views, manual DI via `Injector.java`, MVP pattern

The user can toggle between them via settings. `HomeActivity` is the V2 entry point; `MainActivity` is the V1 entry point.

**All new development should target the `v2/` package.**

### V2 Package Structure

```
v2/
├── app/ # UI layer — one subfolder per screen (home, records, settings, deleted, lostrecords, info, welcome)
│ └── components/ # Reusable Compose components
├── audio/ # Recording and playback logic + foreground services
├── data/ # Data layer — Room DB, data sources, file I/O, prefs
│ ├── room/ # AppDatabase, DAOs, entities
│ ├── model/ # Domain models (Record, SortOrder, etc.)
│ └── Mappers.kt
├── navigation/ # RecorderNavigationGraph.kt + Routes.kt
├── di/ # Hilt modules (AppModule, DatabaseModule, DataSourceModule) + qualifiers
└── theme/ # Compose theme (dark/dynamic color)
```

### Core Patterns

- **Language/UI:** Kotlin, Jetpack Compose, Material3
- **DI:** Hilt (`@HiltAndroidApp`, `@AndroidEntryPoint`, `@HiltViewModel`)
- **Database:** Room
- **Async:** Coroutines with `@IoDispatcher` / `@MainDispatcher` qualifiers
- **Navigation:** Navigation Compose
- **State management:** ViewModels expose immutable state data classes via `mutableStateOf()`. One-shot events use `SharedFlow`.

### Service-Based Audio Architecture

Recording and playback run as **foreground services** (`AudioRecordingService`, `AudioPlaybackService`). ViewModels bind via `ServiceConnection` and receive state via `StateFlow`/`SharedFlow`.

### Entry Points

- `HomeActivity` — V2 entry point
- `MainActivity` — V1 legacy entry point

### Key Non-Obvious Behaviors

- **Broken record recovery:** `BrokenRecordRestorer.kt` detects/repairs WAV/M4A/3GP files interrupted by crash or reboot.
- **Waveform data:** Amplitude samples stored in Room (`Record.amps: IntArray`), decoded via `DecodeService`.
- **Bluetooth mic:** `AudioManagerHelper` monitors Bluetooth state reactively; `HomeViewModel` manages source selection.
- **Preferences:** `PrefsV2` wraps SharedPreferences with Flow-based reactive updates. `Prefs` and `PrefsV2` share the same SharedPreferences file.

## Testing

- Unit tests: `app/src/test/` — use **MockK** (not Mockito) and **Robolectric**
- Instrumented tests: `app/src/androidTest/`
- JaCoCo excludes generated code, Hilt classes, Activities, and Compose components from coverage

## Key Dependencies

| Purpose | Library |
|---|---|
| DI | Hilt 2.59 |
| UI | Jetpack Compose BOM 2026.02, Material3 |
| Navigation | Navigation Compose 2.9 |
| Database | Room 2.8 |
| Playback | android.media.MediaPlayer |
| Audio metadata | jaudiotagger 3.0, mp4parser 1.9 |
| Async | Coroutines 1.10 |
| Logging | Timber 5.0 |
| Test mocking | MockK 1.14 |

42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,48 @@
- Create bookmarks for quick access.
- Personalize the app with colorful themes.

# Test Coverage Reports

The project uses [JaCoCo](https://www.jacoco.org/) for code-coverage reporting. Two Gradle tasks are available:

### Unit-test-only report (no device required)

```bash
./gradlew jacocoTestReport
```

Runs **unit tests** (`testDebugConfigDebugUnitTest`) and generates a coverage report.

| Output | Path |
|----------|-------------------------------------------------------|
| HTML | `app/build/reports/jacoco/html/index.html` |
| XML | `app/build/reports/jacoco/jacocoTestReport.xml` |

### Full report — unit tests + connected (instrumented) tests

> **Prerequisite:** a connected device or running emulator.

```bash
./gradlew jacocoFullReport
```

Runs both **unit tests** and **connected Android tests** (`connectedDebugConfigDebugAndroidTest`), then merges the coverage data into a single report.

| Output | Path |
|----------|-------------------------------------------------------|
| HTML | `app/build/reports/jacoco/htmlFull/index.html` |
| XML | `app/build/reports/jacoco/jacocoFullReport.xml` |

### Coverage verification

```bash
./gradlew jacocoTestCoverageVerification
```

Runs `jacocoFullReport` and then asserts that the overall **line coverage ratio ≥ 5 %**. The build will fail if the threshold is not met.

> **Tip:** For fast local iteration use `jacocoTestReport` (unit tests only). Reserve `jacocoFullReport` / `jacocoTestCoverageVerification` for CI or when you need instrumented-test coverage.

# FAQ
### <b>When option to choose recording directory will be added?</b>
<p>There is no plans to add feature where user can change recording directory. Newer versions of Android added restrictions on ability to interact with device file system. There is no simple way how to implement the feature. So all records are stored in app's private dir. Anyway, all record files available for user to download from app's private dir to a public dir.</p>
Expand Down
117 changes: 0 additions & 117 deletions app/build.gradle

This file was deleted.

Loading