Compare commits

...

164 Commits

Author SHA1 Message Date
Hardcore Sushi 5642e28b44
Fix TODO.md 4 weeks ago
Hardcore Sushi 1b7e5904be
New screenshots 4 weeks ago
Hardcore Sushi cb3fc3c70e
Re-ask only on wrong password 4 weeks ago
Hardcore Sushi 393c458495
Offload file discovery for copy in coroutine 4 weeks ago
Hardcore Sushi cdf98a7190
Handle cryfs inaccessible base dir 4 weeks ago
Hardcore Sushi 2ae41f0f79
Improve file oprations coroutines 4 weeks ago
Muhmmad14333653 f85f9d1c44
Update arabic translation 4 weeks ago
Hardcore Sushi 9fc981fee8
Fix rotation when rebinding camera use cases 4 weeks ago
Hardcore Sushi ad19b9e645
Update dependencies 4 weeks ago
Hardcore Sushi 87ffbc3cc1
Fix unsafe features doc link 1 month ago
Hardcore Sushi b3a25e03e7
Improve video recording: fix freezes & ExoPlayer errors 1 month ago
Hardcore Sushi 4c412be7dc
Best error messages when opening volumes 1 month ago
Hardcore Sushi f4f3239bb1
Fix volume copying 1 month ago
Hardcore Sushi 481558bd56
Add ecryptfs & shufflecake in TODO & Update README 1 month ago
Hardcore Sushi 8d0a797469
v2.0.1 changelog 1 month ago
Hardcore Sushi a4ce35c95d
WiperService 1 month ago
Hardcore Sushi e51bd2ceba
TODO.md & Update dependencies 1 month ago
Hardcore Sushi 2bbf003df5
Recover unregistered hidden volumes 1 month ago
Hardcore Sushi e83cfc9794
Fix password encoding 1 month ago
ctntt 9d1bfd606f
Themed/monochrome icon support
Signed-off-by: Hardcore Sushi <hardcore.sushi@disroot.org>
2 months ago
Hardcore Sushi 49ec2eaf49
Stop always opening files in write mode 2 months ago
Hardcore Sushi 8c9c6a20b9
Really fix proguard-rules.pro 2 months ago
Hardcore Sushi f6d1fc8b67
Fix gradle nosplits 2 months ago
solokot de3a1a9538
Updated Russian v2 translation
Signed-off-by: Hardcore Sushi <hardcore.sushi@disroot.org>
2 months ago
Hardcore Sushi 0a089c46ca
Fix proguard-rules.pro 2 months ago
Hardcore Sushi 05f4610407
v2.0.0 2 months ago
CyanWolf 451f36c770
Update Spanish translation
Signed-off-by: Hardcore Sushi <hardcore.sushi@disroot.org>
2 months ago
Hardcore Sushi df3f84f526
Target Android API level 32 2 months ago
Hardcore Sushi 24215a8b31
Fix crash when default volume gets deleted 2 months ago
Hardcore Sushi eb4e13af46
Disable settings buttons during video recording 2 months ago
Hardcore Sushi aea17aa7cb
Update dependencies 2 months ago
Hardcore Sushi e918a2f94c
New CameraX API 2 months ago
Hardcore Sushi e6761d1798
Update README & fastlane full_description.txt 3 months ago
Hardcore Sushi c434d79c06
Fix video title switching 3 months ago
Hardcore Sushi 821c853a22
Hide navigation bar in full screen mode 3 months ago
Hardcore Sushi 22b1522192
Optional password fallback 3 months ago
Hardcore Sushi 5090a7aa03
Separate color selection & black theme 3 months ago
Hardcore Sushi 1a1d3ea570
Multi volume openings 3 months ago
Hardcore Sushi 2d165c4a20
Monospace font in text editor 4 months ago
Hardcore Sushi 883874a5ab
Refactoring: Constants & FileTypes 4 months ago
Hardcore Sushi 6e500c23e5
Adaptive icon 4 months ago
Hardcore Sushi a726f7a7d0
Fix storage permission requests 4 months ago
Hardcore Sushi 1e75e9a32f
Clear password fields onStop() 4 months ago
Hardcore Sushi 5e9656970a
Update dependencies 4 months ago
Hardcore Sushi 5dbef99949
Fix EncryptedVolumeDataSource EOF 4 months ago
Hardcore Sushi d2f11c85d1
Android 11 support 4 months ago
Hardcore Sushi 25dbcca854
Update libpdfviewer & Fix FFmpeg build & onBackPressed deprecation in AddVolumeActivity 8 months ago
CyanWolf 545275dabc
Update spanish translation 8 months ago
solokot 077f5cc856
Update russian translation 8 months ago
Muhmmad14333653 2e07ee5333
Update arabic translation 8 months ago
Hardcore Sushi 34aad2596d
Async file loading in file viewers 8 months ago
Hardcore Sushi cdc269f2f7
Add pink themes 8 months ago
Hardcore Sushi 991e435e5e
Fix file viewers navigation bar color in dark mode 8 months ago
Hardcore Sushi 7c2f87109a
Allow to open & create volumes without remembering 8 months ago
Hardcore Sushi 4df1086734
More flexible password change when fingerprint is saved 8 months ago
Hardcore Sushi 7cdfc32c31
Direct encrypted files read/write & More compliant EncryptedVolumeDataSource 9 months ago
Hardcore Sushi 8f5afca823
Update dependencies & Fix some bugs 9 months ago
Hardcore Sushi 11cc15536f
Add FLAG_GRANT_READ_URI_PERMISSION for external opens 9 months ago
Hardcore Sushi 2d19895e6d
Truncate files after possible overwrite 9 months ago
Hardcore Sushi e2539a53b9
Set navigation bar color to background color 11 months ago
Hardcore Sushi 17c32f2144
Show volume type in MainActivity 11 months ago
Hardcore Sushi a5b6de1138
BUILD.md: prefer cloning from the Chapril repository 11 months ago
Hardcore Sushi d1ca164934
Allow changing password of CryFS volumes 11 months ago
Hardcore Sushi 1a21a43f05
Gocryptfs JNI cleanup 11 months ago
Hardcore Sushi 4d164944c1
Deleting files in background 11 months ago
Hardcore Sushi 8709abd7d7
Don't cancel file operations when changing configuration 11 months ago
Hardcore Sushi e01932acda
Allow opening CryFS volumes with password hash 11 months ago
Hardcore Sushi cf4927a90b
CryFS 12 months ago
CyanWolf cb5679515c
Update spanish translation
Fix little error
12 months ago
Muhmmad14333653 a728bd8d24
Update arabic translation 12 months ago
Hardcore Sushi 83dd759f36
Fix local reference table overflow in native_list_dir 1 year ago
Hardcore Sushi 5144947a4a
Media player fixes: better handling of RTL & orientation 1 year ago
Muhmmad14333653 6b52eed9d0
update arabic translation
Signed-off-by: Hardcore Sushi <hardcore.sushi@disroot.org>
1 year ago
Muhmmad14333653 2a257d91d0
update Arabic translation
Signed-off-by: Hardcore Sushi <hardcore.sushi@disroot.org>
1 year ago
Hardcore Sushi f837556af5
Fix explorer info bar color in dark mode 1 year ago
Hardcore Sushi b7ab267d16
Arabic translation 1 year ago
Hardcore Sushi 5ea0b8ad41
Actually fix camera icon tint bug 1 year ago
Hardcore Sushi ec348383c6
Fix camera icon tint bug 1 year ago
Hardcore Sushi c8d266150c
Fix explorer menu display 1 year ago
CyanWolf 4bbc9360b4
Update Spanish translation
Added the latest translations and syntax improvements.

Signed-off-by: Hardcore Sushi <hardcore.sushi@disroot.org>
1 year ago
Hardcore Sushi 8aa2be2b05
Update libgocryptfs & Small UX fix 1 year ago
Hardcore Sushi e2248220c4
DroidFS v1.10.0 1 year ago
Hardcore Sushi 7959b20b3f
Update libgocryptfs 1 year ago
solokot 8cebe499f0
Updated Russian translation
Signed-off-by: Hardcore Sushi <hardcore.sushi@disroot.org>
1 year ago
cyanwolfg a22b9d8fa8
Update Spanish translation
Add some missing lines and new translations.

Signed-off-by: Hardcore Sushi <hardcore.sushi@disroot.org>
1 year ago
Hardcore Sushi cba1418417
Fix move operation 1 year ago
Hardcore Sushi b6b8bba666
Save checkbox state if opening volume fails 1 year ago
Hardcore Sushi e00abdf5bb
Switch to Kotlin coroutines 1 year ago
Hardcore Sushi 72cce1d7e1
Show a fingerprint icon when password hash is saved 1 year ago
Hardcore Sushi 55b0ac0daa
Prefill text field with current name when renaming a volume 1 year ago
Hardcore Sushi 53f28e9475
Pin passwords 1 year ago
Hardcore Sushi f1d4b07726
Show total number of selected items 1 year ago
Hardcore Sushi 339309b00d
Fix image viewer rotation handling 1 year ago
Hardcore Sushi e6a1285e0a
Fix camera output rotation 1 year ago
Hardcore Sushi ab48f9219b
CameraActivity: only bind 2 use cases at most + some other fixes 1 year ago
Hardcore Sushi c521c7f998
Open default volume on application startup 1 year ago
Hardcore Sushi 1d13dfbde3
Always show total size & Add some explorer info bar translations 1 year ago
Hardcore Sushi 36ab66fb43
Show number of files & folders in current directory 1 year ago
Hardcore Sushi 1caabc2554
Fix explorer layouts 1 year ago
Hardcore Sushi f541504e07
Refactor RecyclerView adapters 1 year ago
Hardcore Sushi 4de5b41102
Thumbnails cache & Don't do full reload on selection change 1 year ago
Hardcore Sushi 4f9aa55dfe
Explorer grid layout 1 year ago
Hardcore Sushi 91de54018d
Prompt for password if fingerprint authentification fails 1 year ago
Hardcore Sushi 2697eaf11b
Spanish translation 1 year ago
Hardcore Sushi 9e69805ade
Update ptbr translation 1 year ago
Hardcore Sushi 18d0f50094
Update to libpdfviewer 13 1 year ago
Hardcore Sushi e32e106ce3
Fix video player controls 1 year ago
Hardcore Sushi 4608a7a165
Fix MainSettingsFragment crash 1 year ago
Hardcore Sushi 985be2de59
Add HEIC to the image extension list 1 year ago
solokot f07d99efed
Updated Russian translation
Signed-off-by: Hardcore Sushi <hardcore.sushi@disroot.org>
1 year ago
Hardcore Sushi 4a55d826d9
Volume renaming 1 year ago
Hardcore Sushi 2ee7a5b871
Allow changing thumbnail max size 1 year ago
Hardcore Sushi 72321b8ec5
Switch to StyledPlayerView 1 year ago
Hardcore Sushi 7226cc8218
Fix UI bug on too long volume paths 1 year ago
Hardcore Sushi 55be5cd0e7
DroidFS v1.9.0 1 year ago
solokot 3c4515e4e9
Update Russian translation 1 year ago
Hardcore Sushi 29eb34e1d5
New screenshots 1 year ago
Hardcore Sushi d6f727a142
Fix error message when creating volume on external SD card 1 year ago
Hardcore Sushi 6d5fc465c7
Fix UI bug on alert dialogs 1 year ago
Hardcore Sushi ed0b5eb483
Add PDF in OpenAs dialog & libpdfviewer dialog crash fix 1 year ago
Hardcore Sushi fd0296f801
Update libpdfviewer 1 year ago
Hardcore Sushi 58391802be
More accurate directory size 1 year ago
Hardcore Sushi e01b5a3098
Volume copy 1 year ago
Hardcore Sushi bea0906f65
Display file name on video player 1 year ago
Hardcore Sushi 71a314b0a0
New home UI 1 year ago
Hardcore Sushi 842667cdee
Update ptbr translation 1 year ago
Hardcore Sushi e5bcc5cfc2
Update dependencies 1 year ago
Hardcore Sushi 32508344fe
Update PGP key 1 year ago
Hardcore Sushi ee3df7c3bf
Icon for PDF files 1 year ago
Hardcore Sushi b18232615d
PDF viewer 1 year ago
Hardcore Sushi 83efc53edc
Update PGP keyserver 1 year ago
Hardcore Sushi f546e64c34
ImageViwer: retrieve screen size with Resources.getSystem().displayMetrics 1 year ago
Hardcore Sushi 822aba9481
Better build explanation 1 year ago
Hardcore Sushi 3007bf756c
Fix video player UI bug 1 year ago
solokot 87cd88232e
Update russian translation 1 year ago
Hardcore Sushi 832fd1d34b
DoubleTapPlayerView 1 year ago
Hardcore Sushi 3ae7e4df70
Remove DialogSingleChoiceAdapter 1 year ago
Hardcore Sushi 55883172a1
Consider WebP as image 1 year ago
Hardcore Sushi b366fa1877
Fill viewport in text editor 1 year ago
Hardcore Sushi 95eed07719
Natural file name sorting 1 year ago
Hardcore Sushi f15b17c936
Fix scroll issue on OpenActivity & ChangePasswordActivity 1 year ago
Hardcore Sushi 5d6f53b37a
Change icon of mode button when switching between photo & video mode 1 year ago
Hardcore Sushi 23d017780f
Flush previous image before loading the next in ImageViewer 1 year ago
Hardcore Sushi bee2997f90
Update dependencies 1 year ago
Hardcore Sushi 80c5277936
Reset flash state when switching to back camera in video mode 1 year ago
solokot a9d4284b43
Updated Russian translation
Signed-off-by: Hardcore Sushi <hardcore.sushi@disroot.org>
1 year ago
Hardcore Sushi 7ca9398766
Fix size formatting 1 year ago
Hardcore Sushi bd4c935c4c
Downscale image when decoding with BitmapFactory 1 year ago
Hardcore Sushi b65ee230be
Fix flash and timer for video recording 1 year ago
Hardcore Sushi 8b4adfbe21
Update dependencies 1 year ago
Hardcore Sushi 57e93f0b49
Fix video player auto rotation 1 year ago
Hang Hang be802aa5af
Legacy fullscreen mode option & Button to toggle screen orientation in video player 1 year ago
Hardcore Sushi d1a556b8c6
Invalidate options menu when changing explorer elements 1 year ago
solokot 83525159e3
Updated Russian translation to v1.7.0
Signed-off-by: Hardcore Sushi <hardcore.sushi@disroot.org>
2 years ago
Hardcore Sushi 4f8bf860e0
Don't use DayNight themes 2 years ago
Hardcore Sushi 2ee0c679fb
Fix bugs when renaming 2 years ago
Hardcore Sushi 23a20b7ddb
Fix delete icon color bug 2 years ago
Hardcore Sushi fd5ddc02b1
Thumbnails 2 years ago
Hardcore Sushi e3df7be3b5
Switch explorer from ListView to RecyclerView 2 years ago
Hardcore Sushi 65ecdd19ca
Remove some deprecation warnings 2 years ago
Hardcore Sushi d3f0d059f8
Switch from Cyanea to Themes 2 years ago
Hardcore Sushi d572a8d2dc
Update dependencies 2 years ago
Hardcore Sushi 01a9c261f5
Fix image viewer 2 years ago
Hardcore Sushi 1cab607fa1
Decode images with BitmapFactory instead of Glide 2 years ago

6
.gitmodules vendored

@ -1,3 +1,9 @@
[submodule "app/libgocryptfs"]
path = app/libgocryptfs
url = https://forge.chapril.org/hardcoresushi/libgocryptfs.git
[submodule "libpdfviewer"]
path = libpdfviewer
url = https://forge.chapril.org/hardcoresushi/libpdfviewer.git
[submodule "app/libcryfs"]
path = app/libcryfs
url = https://forge.chapril.org/hardcoresushi/libcryfs.git

@ -0,0 +1,108 @@
# Introduction
DroidFS relies on modified versions of the original encrypted filesystems programs to open volumes. [CryFS](https://github.com/cryfs/cryfs) is written in C++ while [gocryptfs](https://github.com/rfjakob/gocryptfs) is written in [Go](https://golang.org). Thus, building DroidFS requires the compilation of native code. However, for the sake of simplicity, the application has been designed in a modular way: you can build a version of DroidFS that supports both Gocryptfs and CryFS, or only one of the two.
Moreover, DroidFS aims to be accessible to as many people as possible. If you encounter any problems or need help with the build, feel free to open an issue, a discussion, or contact me by [email](mailto:hardcore.sushi@disroot.org) or on [Matrix](https://matrix.org): @hardcoresushi:matrix.underworld.fr
# Setup
Install required packages:
```
$ sudo apt-get install openjdk-11-jdk-headless build-essential pkg-config git gnupg2 wget apksigner
```
You also need to manually install the [Android SDK](https://developer.android.com/studio/index.html#command-tools) and the [Android Native Development Kit (NDK)](https://developer.android.com/ndk/downloads) (r23 versions are recommended).
If you want a support for Gocryptfs volumes, you must install [Go](https://golang.org/doc/install) and libssl:
```
$ sudo apt-get install golang-go libssl-dev
```
The code should be authenticated before being built. To verify the signatures, you will need my PGP key:
```
$ gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys AFE384344A45E13A
```
Fingerprint: `B64E FE86 CEE1 D054 F082 1711 AFE3 8434 4A45 E13A` \
Email: `Hardcore Sushi <hardcore.sushi@disroot.org>`
# Download sources
Download DroidFS source code:
```
$ git clone --depth=1 https://forge.chapril.org/hardcoresushi/DroidFS.git
```
Verify sources:
```
$ cd DroidFS
$ git verify-commit HEAD
```
__Don't continue if the verification fails!__
Initialize submodules:
```
$ git submodule update --depth=1 --init
```
[FFmpeg](https://ffmpeg.org) is needed to record encrypted video:
```
$ cd app/ffmpeg
$ git clone --depth=1 https://git.ffmpeg.org/ffmpeg.git
```
If you want Gocryptfs support, you need to download OpenSSL:
```
$ cd ../libgocryptfs
$ wget https://www.openssl.org/source/openssl-1.1.1t.tar.gz
```
Verify OpenSSL signature:
```
$ wget https://www.openssl.org/source/openssl-1.1.1t.tar.gz.asc
$ gpg --verify openssl-1.1.1t.tar.gz.asc openssl-1.1.1t.tar.gz
```
Continue **ONLY** if the signature is **VALID**.
```
$ tar -xzf openssl-1.1.1t.tar.gz
```
If you want CryFS support, initialize libcryfs:
```
$ cd app/libcryfs
$ git submodule update --depth=1 --init
```
# Build
Retrieve your Android NDK installation path, usually something like `/home/\<user\>/Android/SDK/ndk/\<NDK version\>`. Then, make it available in your shell:
```
$ export ANDROID_NDK_HOME="<your ndk path>"
```
Start by compiling FFmpeg:
```
$ cd app/ffmpeg
$ ./build.sh ffmpeg
```
## libgocryptfs
This step is only required if you want Gocryptfs support.
```
$ cd app/libgocryptfs
$ OPENSSL_PATH="./openssl-1.1.1t" ./build.sh
```
## Compile APKs
Gradle build libgocryptfs and libcryfs by default.
To build DroidFS without Gocryptfs support, run:
```
$ ./gradlew assembleRelease -PdisableGocryptfs=true
```
To build DroidFS without CryFS support, run:
```
$ ./gradlew assembleRelease -PdisableCryFS=true
```
If you want to build DroidFS with support for both Gocryptfs and CryFS, just run:
```
$ ./gradlew assembleRelease
```
# Sign APKs
If the build succeeds, you will find the unsigned APKs in `app/build/outputs/apk/release/`. These APKs need to be signed in order to be installed on an Android device.
If you don't already have a keystore, you can create a new one by running:
```
$ keytool -genkey -keystore <output file> -alias <key alias> -keyalg EC -validity 10000
```
Then, sign the APK with:
```
$ apksigner sign --out droidfs.apk -v --ks <keystore> app/build/outputs/apk/release/<unsigned apk file>
```
Now you can install `droidfs.apk` on your device.

@ -1,35 +1,46 @@
# DroidFS
DroidFS is an alternative way to use encrypted overlay filesystems on Android that uses its own internal file explorer instead of mounting virtual volumes.
It currently only works with [gocryptfs](https://github.com/rfjakob/gocryptfs) but support for [CryFS](https://github.com/cryfs/cryfs) could be added in the future.
An alternative way to use encrypted virtual filesystems on Android that uses its own internal file explorer instead of mounting volumes.
It currently supports [gocryptfs](https://github.com/rfjakob/gocryptfs) and [CryFS](https://github.com/cryfs/cryfs).
For mortals: Encrypted storage compatible with already existing softwares.
<p align="center">
<img src="https://forge.chapril.org/hardcoresushi/DroidFS/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png" height="500">
<img src="https://forge.chapril.org/hardcoresushi/DroidFS/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png" height="500">
<img src="https://forge.chapril.org/hardcoresushi/DroidFS/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png" height="500">
<img src="https://forge.chapril.org/hardcoresushi/DroidFS/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png" height="500">
<img src="https://forge.chapril.org/hardcoresushi/DroidFS/raw/branch/master/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png" height="500">
</p>
# Disclamer
# Disclaimer
DroidFS is provided "as is", without any warranty of any kind.
It shouldn't be considered as an absolute safe way to store files.
DroidFS cannot protect you from screen recording apps, keyloggers, apk backdooring, compromised root accesses, memory dumps etc.
Do not use this app with volumes containing sensitive data unless you know exactly what you are doing.
# Features
- Compatible with original encrypted volume implementations
- Internal support for video, audio, images, text and PDF files
- Built-in camera to take on-the-fly encrypted photos and videos
- Unlocking volumes using fingerprint authentication
- Volume auto-locking when the app goes in background
_For upcoming features, see [TODO.md](https://forge.chapril.org/hardcoresushi/DroidFS/src/branch/master/TODO.md)._
# Unsafe features
DroidFS allows you to enable/disable unsafe features to fit your needs between security and comfort.
It is strongly recommended to read the documentation of a feature before enabling it.
Some available features are considered risky and are therefore disabled by default. It is strongly recommended that you read the following documentation if you wish to activate one of these options.
<ul>
<li><h4>Allow screenshots:</h4>
Disable the secure flag of DroidFS activities. This will allow you to take screenshots from the app, but will also allow other apps to record the screen while using DroidFS.
Note: apps with root access don't care about this flag: they can take screenshots or record the screen of any app without any permissions.
</li>
<li><h4>Allow opening files with other applications *:</h4>
<li><h4>Allow opening files with other applications*:</h4>
Decrypt and open file using external apps. These apps could save and send the files thus opened.
</li>
<li><h4>Allow exporting files:</h4>
Decrypt and write file to disk (external storage). Any app with storage permissions could access exported files.
</li>
<li><h4>Allow sharing files via the android share menu *:</h4>
<li><h4>Allow sharing files via the android share menu*:</h4>
Decrypt and share file with other apps. These apps could save and send the files thus shared.
</li>
<li><h4>Keep volume open when the app goes in background:</h4>
@ -46,12 +57,12 @@ It is strongly recommended to read the documentation of a feature before enablin
<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" height="75">
</a>
You can download DroidFS from [F-Droid](https://f-droid.org/packages/sushi.hardcore.droidfs) or from the "Releases" section in the repo.
You can download DroidFS from [F-Droid](https://f-droid.org/packages/sushi.hardcore.droidfs) or from the "Releases" section in this repository.
APKs availables here are signed with my PGP key available on keyservers:
APKs available here are signed with my PGP key available on keyservers:
`gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 007F84120107191E` \
Fingerprint: `BD5621479E7B74D36A405BE8007F84120107191E` \
`gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys AFE384344A45E13A` \
Fingerprint: `B64E FE86 CEE1 D054 F082 1711 AFE3 8434 4A45 E13A` \
Email: `Hardcore Sushi <hardcore.sushi@disroot.org>`
To verify APKs, save the PGP-signed message to a file and run `gpg --verify <the file>`. __Don't install any APK if the verification fails !__
@ -65,17 +76,17 @@ __Don't install the APK if the checksums don't match!__
F-Droid APKs should be signed with the F-Droid key. More details [here](https://f-droid.org/docs/Release_Channels_and_Signing_Keys).
# Permissions
DroidFS need some permissions to work properly. Here is why:
DroidFS needs some permissions for certain features. However, you are free to deny them if you do not wish to use these features.
<ul>
<li><h4>Read & write access to shared storage:</h4>
Required for creating, opening and modifying volumes and for importing/exporting files to/from volumes.
Required to access volumes located on shared storage.
</li>
<li><h4>Biometric/Fingerprint hardware:</h4>
Required to encrypt/decrypt password hashes using a fingerprint protected key.
</li>
<li><h4>Camera:</h4>
Needed to take photos & videos directly encrypted inside DroidFS. You can deny this permission if you don't want to use it.
Required to take encrypted photos or videos directly from the app.
</li>
<li><h4>Record audio:</h4>
Required if you want sound on video recorded with DroidFS.
@ -83,75 +94,24 @@ DroidFS need some permissions to work properly. Here is why:
</ul>
# Limitations
DroidFS use some parts of the original gocryptfs code, which is designed to run on Linux x86 systems: it accesses the underlying file system with file paths and syscalls. However in Android, you can't access other apps files with file paths. Instead, you must use the [ContentProvider](https://developer.android.com/guide/topics/providers/content-providers) API. And obviously, the original gocryptfs code doesn't work with this API. This is why DroidFS can't open volumes provided by other applications, such as cloud storage clients. You can only use DroidFS with volumes located on shared storage or in the app's internal storage (hidden volumes). External storage such as SD cards are only supported in read-only access for now.
# Build
Most of the original gocryptfs code was used as is (written in Go) and compiled to native code. That's why you need [Go](https://golang.org) and the [Android Native Development Kit (NDK)](https://developer.android.com/ndk/) to build DroidFS from source.
#### Install Requirements
- [Android Studio](https://developer.android.com/studio/)
- [Android NDK and CMake](https://developer.android.com/studio/projects/install-ndk) (OpenSSL build fails with NDK versions higher than v22. It should pass with NDK v21.4.7075529 and lower)
- [Go](https://golang.org/doc/install) (on debian: `$ sudo apt-get install golang-go`)
DroidFS works as a wrapper around modified versions of the original encrypted container implementations ([libgocryptfs](https://forge.chapril.org/hardcoresushi/libgocryptfs) and [libcryfs](https://forge.chapril.org/hardcoresushi/libcryfs)). These programs were designed to run on standard x86 Linux systems: they access the underlying file system with file paths and syscalls. However, on Android, you can't access files from other applications using file paths. Instead, one has to use the [ContentProvider](https://developer.android.com/guide/topics/providers/content-providers) API. Obviously, neither Gocryptfs nor CryFS support this API. As a result, DroidFS cannot open volumes provided by other applications (such as cloud storage clients), nor can it allow other applications to access encrypted volumes once opened.
#### Download Sources
```
$ git clone https://github.com/hardcore-sushi/DroidFS.git
```
Download [libgocryptfs](https://forge.chapril.org/hardcoresushi/libgocryptfs):
```
$ cd DroidFS
$ git submodule update --init
```
libgocryptfs needs OpenSSL:
```
$ cd app/libgocryptfs
$ wget https://www.openssl.org/source/openssl-1.1.1l.tar.gz
```
Verify OpenSSL signature:
```
$ wget https://www.openssl.org/source/openssl-1.1.1l.tar.gz.asc
$ gpg --verify openssl-1.1.1l.tar.gz.asc openssl-1.1.1l.tar.gz
```
Continue **ONLY** if the signature is **VALID**.
```
$ tar -xvzf openssl-1.1.1l.tar.gz
```
DroidFS also need [FFmpeg](https://ffmpeg.org) to record encrypted video:
```
$ cd app/ffmpeg
$ git clone --depth=1 https://git.ffmpeg.org/ffmpeg.git
```
Due to Android's storage restrictions, encrypted volumes located on SD cards must be placed under `/Android/data/sushi.hardcore.droidfs/` if you want DroidFS to be able to modify them.
#### Build
First, we need to install some dependencies:
```
$ sudo apt-get install libcrypto++-dev libssl-dev pkg-config
```
And also Go dependencies:
```
$ go get golang.org/x/sys/unix golang.org/x/sys/cpu golang.org/x/crypto/hkdf github.com/jacobsa/crypto/siv github.com/rfjakob/eme
```
Then, retrieve your Android NDK installation path, usually someting like "/home/\<user\>/Android/SDK/ndk/\<NDK version\>". We can now build libgocryptfs:
```
$ cd DroidFS/app/libgocryptfs
$ env ANDROID_NDK_HOME="<your ndk path>" OPENSSL_PATH="./openssl-1.1.1l" ./build.sh
```
And also FFmpeg:
```
$ cd app/ffmpeg
$ env ANDROID_NDK_HOME="<your ndk path>" ./build.sh ffmpeg
```
Then, open the DroidFS project with Android Studio. \
If a device (virtual or physical) is connected, just click on "Run". \
If you want to generate a signed APK, you can follow this [post](https://stackoverflow.com/a/28938286).
# Building from source
You can follow the instructions in [BUILD.md](BUILD.md) to build DroidFS from source.
# Third party code
Thanks to these open source projects that DroidFS uses:
### Modified code:
- [gocryptfs](https://github.com/rfjakob/gocryptfs) to encrypt your data
- Encrypted filesystems (to protect your data):
- [libgocryptfs](https://forge.chapril.org/hardcoresushi/libgocryptfs) (forked from [gocryptfs](https://github.com/rfjakob/gocryptfs))
- [libcryfs](https://forge.chapril.org/hardcoresushi/libcryfs) (forked from [CryFS](https://github.com/cryfs/cryfs))
- [libpdfviewer](https://forge.chapril.org/hardcoresushi/libpdfviewer) (forked from [PdfViewer](https://github.com/GrapheneOS/PdfViewer)) to open PDF files
- [DoubleTapPlayerView](https://github.com/vkay94/DoubleTapPlayerView) to add double-click controls to the video player
### Borrowed code:
- [MaterialFiles](https://github.com/zhanghai/MaterialFiles) for Kotlin natural sorting implementation
### Libraries:
- [Cyanea](https://github.com/jaredrummler/Cyanea) to customize UI
- [Glide](https://github.com/bumptech/glide/) to display pictures
- [Glide](https://github.com/bumptech/glide) to display pictures
- [ExoPlayer](https://github.com/google/ExoPlayer) to play media files

@ -0,0 +1,31 @@
# TODO
Here's a list of features that it would be nice to have in DroidFS. As this is a FLOSS project, there are no special requirements on *when* or even *if* these features will be implemented, but contributions are greatly appreciated.
## Security
- [hardened_malloc](https://github.com/GrapheneOS/hardened_malloc) compatibility ([#181](https://github.com/hardcore-sushi/DroidFS/issues/181))
- Internal keyboard for passwords
## UX
- File associations editor
- Optional discovery before file operations
- Modifiable CryFS scrypt parameters
- Alert dialog showing details of file operations
- Internal file browser to select volumes
## Encryption software support
- [Shufflecake](https://shufflecake.net): plausible deniability for multiple hidden filesystems on Linux (would be absolutely awesome to have but quite difficult)
- [fscrypt](https://www.kernel.org/doc/html/latest/filesystems/fscrypt.html): filesystem encryption at the kernel level
## Health
- F-Droid ABI split
- OpenSSL & FFmpeg as git submodules (useful for F-Droid)
- Remove all android:configChanges from AndroidManifest.xml
- More efficient thumbnails cache
- Guide for translators
- Usage & code documentation
- Automated tests
## And:
- All the [feature requests on the GitHub repo](https://github.com/hardcore-sushi/DroidFS/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement)
- All the [feature requests on the Gitea repo](https://forge.chapril.org/hardcoresushi/DroidFS/issues?q=&state=open&labels=748)

@ -1,27 +1,27 @@
cmake_minimum_required(VERSION 3.10)
add_library(
gocryptfs
SHARED
IMPORTED
)
project(DroidFS)
set_target_properties(
gocryptfs
PROPERTIES IMPORTED_LOCATION
${PROJECT_SOURCE_DIR}/libgocryptfs/build/${ANDROID_ABI}/libgocryptfs.so
)
option(GOCRYPTFS "build libgocryptfs" ON)
option(CRYFS "build libcryfs" ON)
add_library(
gocryptfs_jni
SHARED
src/main/native/gocryptfs_jni.c
)
if (GOCRYPTFS)
add_library(gocryptfs SHARED IMPORTED)
set_target_properties(
gocryptfs
PROPERTIES IMPORTED_LOCATION
${PROJECT_SOURCE_DIR}/libgocryptfs/build/${ANDROID_ABI}/libgocryptfs.so
)
add_library(gocryptfs_jni SHARED src/main/native/gocryptfs_jni.c)
target_include_directories(gocryptfs_jni PRIVATE ${PROJECT_SOURCE_DIR}/libgocryptfs/build/${ANDROID_ABI})
target_link_libraries(gocryptfs_jni gocryptfs)
endif()
target_link_libraries(
gocryptfs_jni
gocryptfs
)
if (CRYFS)
add_subdirectory(${PROJECT_SOURCE_DIR}/libcryfs)
add_library(cryfs_jni SHARED src/main/native/libcryfs.c)
target_link_libraries(cryfs_jni libcryfs-jni)
endif()
add_library(
avformat
@ -65,14 +65,12 @@ add_library(
src/main/native/libmux.c
)
target_include_directories(mux PRIVATE ${PROJECT_SOURCE_DIR}/ffmpeg/build/${ANDROID_ABI})
target_link_libraries(
mux
avformat
avcodec
avutil
)
include_directories(
${PROJECT_SOURCE_DIR}/libgocryptfs/build/${ANDROID_ABI}
${PROJECT_SOURCE_DIR}/ffmpeg/build/${ANDROID_ABI}
log
)

@ -1,10 +1,29 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
if (hasProperty("disableCryFS")) {
ext.disableCryFS = getProperty("disableCryFS")
} else {
ext.disableCryFS = false
}
if (hasProperty("disableGocryptfs")) {
ext.disableGocryptfs = getProperty("disableGocryptfs")
} else {
ext.disableGocryptfs = false
}
if (hasProperty("nosplits")) {
ext.splits = false
} else {
ext.splits = true
}
android {
compileSdkVersion 31
buildToolsVersion "31"
ndkVersion "23.0.7599858"
compileSdkVersion 33
buildToolsVersion "33.0.0"
ndkVersion "25.1.8937393"
namespace "sushi.hardcore.droidfs"
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
@ -13,16 +32,25 @@ android {
defaultConfig {
applicationId "sushi.hardcore.droidfs"
minSdkVersion 21
targetSdkVersion 29
versionCode 19
versionName "1.6.0"
targetSdkVersion 32
versionCode 32
versionName "2.0.2"
ndk {
abiFilters "x86", "x86_64", "armeabi-v7a", "arm64-v8a"
}
externalNativeBuild.cmake {
if (project.ext.disableGocryptfs) {
arguments "-DGOCRYPTFS=OFF"
}
if (project.ext.disableCryFS) {
arguments "-DCRYFS=OFF"
}
}
}
if (!file("fdroid").exists()) {
if (project.ext.splits) {
splits {
abi {
enable true
@ -33,6 +61,8 @@ android {
applicationVariants.all { variant ->
variant.resValue "string", "versionName", variant.versionName
buildConfigField "boolean", "CRYFS_DISABLED", "${project.ext.disableCryFS}"
buildConfigField "boolean", "GOCRYPTFS_DISABLED", "${project.ext.disableGocryptfs}"
}
buildFeatures {
@ -41,9 +71,13 @@ android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
postprocessing {
removeUnusedCode true
removeUnusedResources true
obfuscate false
optimizeCode true
proguardFiles 'proguard-rules.pro'
}
}
}
@ -52,32 +86,46 @@ android {
path file('CMakeLists.txt')
}
}
sourceSets {
main {
java {
exclude 'androidx/camera/video/originals/**'
}
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation project(":libpdfviewer:app")
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.core:core-ktx:1.6.0"
implementation "androidx.appcompat:appcompat:1.3.1"
implementation "androidx.constraintlayout:constraintlayout:2.1.1"
implementation 'androidx.core:core-ktx:1.10.0'
implementation "androidx.appcompat:appcompat:1.6.1"
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
def lifecycle_version = "2.6.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
implementation "androidx.sqlite:sqlite-ktx:2.1.0"
implementation "androidx.preference:preference-ktx:1.1.1"
implementation "androidx.sqlite:sqlite-ktx:2.3.1"
implementation "androidx.preference:preference-ktx:1.2.0"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "com.jaredrummler:cyanea:1.0.2"
implementation "com.github.bumptech.glide:glide:4.12.0"
implementation "androidx.biometric:biometric:1.1.0"
implementation 'com.google.android.material:material:1.9.0'
implementation 'com.github.bumptech.glide:glide:4.15.1'
implementation "androidx.biometric:biometric-ktx:1.2.0-alpha05"
def exoplayer_version = "2.15.1"
def exoplayer_version = "2.18.6"
implementation "com.google.android.exoplayer:exoplayer-core:$exoplayer_version"
implementation "com.google.android.exoplayer:exoplayer-ui:$exoplayer_version"
implementation "androidx.concurrent:concurrent-futures:1.1.0"
def camerax_v1 = "1.1.0-alpha10"
implementation "androidx.camera:camera-camera2:$camerax_v1"
implementation "androidx.camera:camera-lifecycle:$camerax_v1"
def camerax_v2 = "1.0.0-alpha30"
implementation "androidx.camera:camera-view:$camerax_v2"
implementation "androidx.camera:camera-extensions:$camerax_v2"
def camerax_version = "1.3.0-alpha06"
implementation "androidx.camera:camera-camera2:$camerax_version"
implementation "androidx.camera:camera-lifecycle:$camerax_version"
implementation "androidx.camera:camera-view:$camerax_version"
implementation "androidx.camera:camera-extensions:$camerax_version"
def autoValueVersion = "1.10.1"
implementation "com.google.auto.value:auto-value-annotations:$autoValueVersion"
annotationProcessor "com.google.auto.value:auto-value:$autoValueVersion"
}

@ -1,9 +1,11 @@
#!/bin/bash
if [ -z ${ANDROID_NDK_HOME+x} ]; then
echo "Error: \$ANDROID_NDK_HOME is not defined."
echo "Error: \$ANDROID_NDK_HOME is not defined." >&2
exit 1
elif [ $# -lt 1 ]; then
echo "Usage: $0 <FFmpeg source directory> [<ABI>]"
echo "Usage: $0 <FFmpeg source directory> [<ABI>]" >&2
exit 1
else
FFMPEG_DIR=$1
compile_for_arch() {
@ -61,6 +63,7 @@ else
--disable-sndio \
--disable-schannel \
--disable-securetransport \
--disable-vulkan \
--disable-xlib \
--disable-zlib \
--disable-cuvid \
@ -76,7 +79,8 @@ else
mkdir -p build/$1/libavformat build/$1/libavcodec build/$1/libavutil &&
cp $FFMPEG_DIR/libavformat/*.h $FFMPEG_DIR/libavformat/libavformat.so build/$1/libavformat &&
cp $FFMPEG_DIR/libavcodec/*.h $FFMPEG_DIR/libavcodec/libavcodec.so build/$1/libavcodec &&
cp $FFMPEG_DIR/libavutil/*.h $FFMPEG_DIR/libavutil/libavutil.so build/$1/libavutil
cp $FFMPEG_DIR/libavutil/*.h $FFMPEG_DIR/libavutil/libavutil.so build/$1/libavutil ||
exit 1
}
export PATH=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH

@ -0,0 +1 @@
Subproject commit 3c56f86d86afacaf4a07ae77aa3d146764d587ec

@ -1 +1 @@
Subproject commit bd5d53f50eb274ed084e9f363ccfbe30d9061039
Subproject commit ab3e7886767d31f32baebcd72ebe5f098a70d65b

@ -25,7 +25,7 @@
-keepclassmembers class sushi.hardcore.droidfs.explorers.ExplorerElement {
static sushi.hardcore.droidfs.explorers.ExplorerElement new(...);
}
-keepclassmembers class sushi.hardcore.droidfs.video_recording.MediaMuxer {
-keepclassmembers class sushi.hardcore.droidfs.video_recording.FFmpegMuxer {
void writePacket(byte[]);
void seek(long);
}

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="sushi.hardcore.droidfs"
android:installLocation="auto">
<permission
android:name="${applicationId}.WRITE_TEMPORARY_STORAGE"
android:protectionLevel="signature" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.CAMERA" />
@ -25,68 +25,40 @@
tools:node="remove" /> <!--removing this permission automatically added by exoplayer-->
<application
android:name=".ColoredApplication"
android:allowBackup="false"
android:icon="@mipmap/icon_launcher"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".CameraActivity"
android:screenOrientation="nosensor" />
<activity
android:name=".SettingsActivity"
android:label="@string/title_activity_settings"
android:parentActivityName=".MainActivity" />
<activity android:name=".explorers.ExplorerActivity" />
<activity android:name=".explorers.ExplorerActivityPick" />
<activity android:name=".explorers.ExplorerActivityDrop" />
<activity
android:name=".OpenActivity"
android:parentActivityName=".MainActivity"
android:screenOrientation="nosensor"
android:windowSoftInputMode="adjustPan">
android:theme="@style/BaseTheme"
android:name=".VolumeManagerApp"
android:fullBackupContent="false"
android:dataExtractionRules="@xml/backup_rules">
<activity android:name=".MainActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter android:label="@string/share_menu_label">
<action android:name="android.intent.action.SEND" />
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
<activity
android:name=".CreateActivity"
android:parentActivityName=".MainActivity"
android:screenOrientation="nosensor" />
<activity
android:name=".ChangePasswordActivity"
android:parentActivityName=".MainActivity"
android:screenOrientation="nosensor"
android:windowSoftInputMode="adjustPan" />
<activity
android:name=".MainActivity"
android:screenOrientation="nosensor">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".file_viewers.ImageViewer"
android:configChanges="screenSize|orientation" /> <!-- don't reload content on configuration change -->
<activity
android:name=".file_viewers.VideoPlayer"
android:configChanges="screenSize|orientation" />
<activity
android:name=".file_viewers.AudioPlayer"
android:configChanges="screenSize|orientation" />
<activity
android:name=".file_viewers.TextEditor"
android:configChanges="screenSize|orientation" />
<activity android:name=".SettingsActivity" android:label="@string/title_activity_settings"/>
<activity android:name=".add_volume.AddVolumeActivity" android:windowSoftInputMode="adjustResize"/>
<activity android:name=".ChangePasswordActivity" android:windowSoftInputMode="adjustResize"/>
<activity android:name=".explorers.ExplorerActivity"/>
<activity android:name=".explorers.ExplorerActivityPick"/>
<activity android:name=".explorers.ExplorerActivityDrop"/>
<activity android:name=".file_viewers.ImageViewer"/>
<activity android:name=".file_viewers.VideoPlayer" android:configChanges="screenSize|orientation" />
<activity android:name=".file_viewers.PdfViewer" android:configChanges="screenSize|orientation" android:theme="@style/AppTheme" />
<activity android:name=".file_viewers.AudioPlayer" android:configChanges="screenSize|orientation" />
<activity android:name=".file_viewers.TextEditor" android:configChanges="screenSize|orientation" />
<activity android:name=".CameraActivity" android:screenOrientation="nosensor" />
<service android:name=".WiperService" android:exported="false" android:stopWithTask="false"/>
<service android:name=".file_operations.FileOperationService" android:exported="false"/>
<receiver android:name=".file_operations.NotificationBroadcastReceiver" android:exported="false">

@ -0,0 +1,14 @@
package androidx.camera.video
import android.media.MediaCodec
import android.media.MediaFormat
import java.nio.ByteBuffer
interface MediaMuxer {
fun setOrientationHint(degree: Int)
fun release()
fun addTrack(mediaFormat: MediaFormat): Int
fun start()
fun writeSampleData(trackIndex: Int, buffer: ByteBuffer, bufferInfo: MediaCodec.BufferInfo)
fun stop()
}

@ -0,0 +1,16 @@
package androidx.camera.video
import android.location.Location
class MuxerOutputOptions(private val mediaMuxer: MediaMuxer): OutputOptions(MuxerOutputOptionsInternal()) {
private class MuxerOutputOptionsInternal: OutputOptionsInternal() {
override fun getFileSizeLimit(): Long = FILE_SIZE_UNLIMITED.toLong()
override fun getDurationLimitMillis(): Long = DURATION_UNLIMITED.toLong()
override fun getLocation(): Location? = null
}
fun getMediaMuxer(): MediaMuxer = mediaMuxer
}

@ -0,0 +1,181 @@
/*
* Copyright 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.camera.video;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import androidx.annotation.CheckResult;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.RequiresPermission;
import androidx.camera.core.impl.utils.ContextUtil;
import androidx.core.content.PermissionChecker;
import androidx.core.util.Consumer;
import androidx.core.util.Preconditions;
import java.util.concurrent.Executor;
/**
* A recording that can be started at a future time.
*
* <p>A pending recording allows for configuration of a recording before it is started. Once a
* pending recording is started with {@link #start(Executor, Consumer)}, any changes to the pending
* recording will not affect the actual recording; any modifications to the recording will need
* to occur through the controls of the {@link SucklessRecording} class returned by
* {@link #start(Executor, Consumer)}.
*
* <p>A pending recording can be created using one of the {@link Recorder} methods for starting a
* recording such as {@link Recorder#prepareRecording(Context, MediaStoreOutputOptions)}.
* <p>There may be more settings that can only be changed per-recorder instead of per-recording,
* because it requires expensive operations like reconfiguring the camera. For those settings, use
* the {@link Recorder.Builder} methods to configure before creating the {@link Recorder}
* instance, then create the pending recording with it.
*/
@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
@SuppressLint("RestrictedApi")
public final class SucklessPendingRecording {
private final Context mContext;
private final SucklessRecorder mRecorder;
private final OutputOptions mOutputOptions;
private Consumer<VideoRecordEvent> mEventListener;
private Executor mListenerExecutor;
private boolean mAudioEnabled = false;
SucklessPendingRecording(@NonNull Context context, @NonNull SucklessRecorder recorder,
@NonNull OutputOptions options) {
// Application context is sufficient for all our needs, so store that to avoid leaking
// unused resources. For attribution, ContextUtil.getApplicationContext() will retain the
// attribution tag from the original context.
mContext = ContextUtil.getApplicationContext(context);
mRecorder = recorder;
mOutputOptions = options;
}
/**
* Returns an application context which was retrieved from the {@link Context} used to
* create this object.
*/
@NonNull
Context getApplicationContext() {
return mContext;
}
@NonNull
SucklessRecorder getRecorder() {
return mRecorder;
}
@NonNull
OutputOptions getOutputOptions() {
return mOutputOptions;
}
@Nullable
Executor getListenerExecutor() {
return mListenerExecutor;
}
@Nullable
Consumer<VideoRecordEvent> getEventListener() {
return mEventListener;
}
boolean isAudioEnabled() {
return mAudioEnabled;
}