From 15f288be118b691b0b9a264f14c53a2a273e3acd Mon Sep 17 00:00:00 2001 From: Hardcore Sushi Date: Thu, 18 Jul 2024 22:10:47 +0200 Subject: [PATCH] Auto gocryptfs cipher by default & Fix FileOperationsService notification permission request --- app/build.gradle | 5 +- .../sushi/hardcore/droidfs/MainActivity.kt | 1 + .../add_volume/CreateVolumeFragment.kt | 6 +- .../file_operations/FileOperationService.kt | 62 ++++++++++++------- .../hardcore/droidfs/util/AndroidUtils.kt | 3 +- app/src/main/res/values-ar/arrays.xml | 20 ------ app/src/main/res/values-tr/arrays.xml | 20 ------ app/src/main/res/values/arrays.xml | 2 +- 8 files changed, 47 insertions(+), 72 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index ece801d..76a46ff 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -116,7 +116,6 @@ dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version" - implementation "androidx.sqlite:sqlite-ktx:2.4.0" implementation "androidx.preference:preference-ktx:1.2.1" implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" implementation 'com.google.android.material:material:1.12.0' @@ -128,14 +127,14 @@ dependencies { implementation "androidx.media3:media3-ui:$media3_version" implementation "androidx.media3:media3-datasource:$media3_version" - implementation "androidx.concurrent:concurrent-futures:1.1.0" - def camerax_version = "1.3.3" 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" + // dependencies needed by CameraX patch + implementation "androidx.concurrent:concurrent-futures:1.1.0" def autoValueVersion = '1.10.4' implementation "com.google.auto.value:auto-value-annotations:$autoValueVersion" annotationProcessor "com.google.auto.value:auto-value:$autoValueVersion" diff --git a/app/src/main/java/sushi/hardcore/droidfs/MainActivity.kt b/app/src/main/java/sushi/hardcore/droidfs/MainActivity.kt index 5495262..21ebd1f 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/MainActivity.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/MainActivity.kt @@ -299,6 +299,7 @@ class MainActivity : BaseActivity(), VolumeAdapter.Listener { selectedVolumePosition = volumeAdapter.selectedItems.elementAt(0) val volume = volumeAdapter.volumes[selectedVolumePosition!!] if (volume.isHidden) { + (application as VolumeManagerApp).isStartingExternalApp = true PathUtils.safePickDirectory(pickDirectory, this, theme) } else { val hiddenVolumeFile = File(VolumeData.getHiddenVolumeFullPath(filesDir.path, volume.shortName)) diff --git a/app/src/main/java/sushi/hardcore/droidfs/add_volume/CreateVolumeFragment.kt b/app/src/main/java/sushi/hardcore/droidfs/add_volume/CreateVolumeFragment.kt index a0c796c..ebaace6 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/add_volume/CreateVolumeFragment.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/add_volume/CreateVolumeFragment.kt @@ -175,9 +175,9 @@ class CreateVolumeFragment: Fragment() { volumeFile.mkdirs() val result = if (volumeTypes[binding.spinnerVolumeType.selectedItemPosition] == resources.getString(R.string.gocryptfs)) { val xchacha = when (binding.spinnerCipher.selectedItemPosition) { - 0 -> 0 - 1 -> 1 - else -> -1 + 0 -> -1 // auto + 1 -> 0 // AES-GCM + else -> 1 // XChaCha20-Poly1305 } generateResult(GocryptfsVolume.createAndOpenVolume( volumePath, diff --git a/app/src/main/java/sushi/hardcore/droidfs/file_operations/FileOperationService.kt b/app/src/main/java/sushi/hardcore/droidfs/file_operations/FileOperationService.kt index 7ed2cc2..4cc66d2 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/file_operations/FileOperationService.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/file_operations/FileOperationService.kt @@ -17,12 +17,13 @@ import android.os.Bundle import android.os.IBinder import android.provider.Settings import android.util.Log -import androidx.activity.result.ActivityResultLauncher import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.core.app.ServiceCompat import androidx.core.content.ContextCompat import androidx.documentfile.provider.DocumentFile +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Deferred import kotlinx.coroutines.Dispatchers @@ -90,14 +91,27 @@ class FileOperationService : Service() { */ fun bind(activity: BaseActivity, onBound: (FileOperationService) -> Unit) { val helper = AndroidUtils.NotificationPermissionHelper(activity) - activity.bindService(Intent(activity, FileOperationService::class.java), object : ServiceConnection { + lateinit var service: FileOperationService + val serviceConnection = object : ServiceConnection { override fun onServiceConnected(className: ComponentName, binder: IBinder) { onBound((binder as FileOperationService.LocalBinder).getService().also { - it.notificationPermissionHelper = helper + service = it + it.notificationPermissionHelpers.addLast(helper) }) } override fun onServiceDisconnected(arg0: ComponentName) {} - }, Context.BIND_AUTO_CREATE) + } + activity.lifecycle.addObserver(object : DefaultLifecycleObserver { + override fun onDestroy(owner: LifecycleOwner) { + activity.unbindService(serviceConnection) + service.notificationPermissionHelpers.removeLast() + } + }) + activity.bindService( + Intent(activity, FileOperationService::class.java), + serviceConnection, + Context.BIND_AUTO_CREATE + ) } } @@ -105,7 +119,7 @@ class FileOperationService : Service() { private val binder = LocalBinder() private lateinit var volumeManger: VolumeManager private var serviceScope = MainScope() - private lateinit var notificationPermissionHelper: AndroidUtils.NotificationPermissionHelper + private val notificationPermissionHelpers = ArrayDeque>(2) private var askForNotificationPermission = true private lateinit var notificationManager: NotificationManagerCompat private val notifications = HashMap() @@ -293,25 +307,27 @@ class FileOperationService : Service() { } pendingTask = task if (askForNotificationPermission) { - notificationPermissionHelper.askAndRun { granted -> - if (granted) { - processPendingTask() - } else { - CustomAlertDialogBuilder(notificationPermissionHelper.activity, notificationPermissionHelper.activity.theme) - .setTitle(R.string.warning) - .setMessage(R.string.notification_denied_msg) - .setPositiveButton(R.string.settings) { _, _ -> - (application as VolumeManagerApp).isStartingExternalApp = true - notificationPermissionHelper.activity.startActivity( - Intent( - Settings.ACTION_APPLICATION_DETAILS_SETTINGS, - Uri.fromParts("package", packageName, null) + with (notificationPermissionHelpers.last()) { + askAndRun { granted -> + if (granted) { + processPendingTask() + } else { + CustomAlertDialogBuilder(activity, activity.theme) + .setTitle(R.string.warning) + .setMessage(R.string.notification_denied_msg) + .setPositiveButton(R.string.settings) { _, _ -> + (application as VolumeManagerApp).isStartingExternalApp = true + activity.startActivity( + Intent( + Settings.ACTION_APPLICATION_DETAILS_SETTINGS, + Uri.fromParts("package", packageName, null) + ) ) - ) - } - .setNegativeButton(R.string.later, null) - .setOnDismissListener { processPendingTask() } - .show() + } + .setNegativeButton(R.string.later, null) + .setOnDismissListener { processPendingTask() } + .show() + } } } askForNotificationPermission = false // only ask once per service instance diff --git a/app/src/main/java/sushi/hardcore/droidfs/util/AndroidUtils.kt b/app/src/main/java/sushi/hardcore/droidfs/util/AndroidUtils.kt index 93edb0e..7bd6509 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/util/AndroidUtils.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/util/AndroidUtils.kt @@ -7,7 +7,6 @@ import android.content.Context import android.content.SharedPreferences import android.content.pm.PackageManager import android.os.Build -import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat @@ -31,7 +30,7 @@ object AndroidUtils { * * Must be initialized before [Activity.onCreate]. */ - class NotificationPermissionHelper(val activity: A) { + class NotificationPermissionHelper(val activity: A) { private var listener: ((Boolean) -> Unit)? = null private val launcher = activity.registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted -> listener?.invoke(granted) diff --git a/app/src/main/res/values-ar/arrays.xml b/app/src/main/res/values-ar/arrays.xml index e33ccae..3dce6d6 100644 --- a/app/src/main/res/values-ar/arrays.xml +++ b/app/src/main/res/values-ar/arrays.xml @@ -1,24 +1,4 @@ - - AES-GCM - XChaCha20-Poly1305 - @string/auto - - - - xchacha20-poly1305 - aes-256-gcm - aes-128-gcm - twofish-256-gcm - twofish-128-gcm - serpent-256-gcm - serpent-128-gcm - cast-256-gcm - mars-448-gcm - mars-256-gcm - mars-128-gcm - - اسم حجم diff --git a/app/src/main/res/values-tr/arrays.xml b/app/src/main/res/values-tr/arrays.xml index a5bbc76..d30ad94 100644 --- a/app/src/main/res/values-tr/arrays.xml +++ b/app/src/main/res/values-tr/arrays.xml @@ -1,24 +1,4 @@ - - AES-GCM - XChaCha20-Poly1305 - @string/auto - - - - xchacha20-poly1305 - aes-256-gcm - aes-128-gcm - twofish-256-gcm - twofish-128-gcm - serpent-256-gcm - serpent-128-gcm - cast-256-gcm - mars-448-gcm - mars-256-gcm - mars-128-gcm - - Ad Boyut diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 45c669a..869e3b6 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -1,8 +1,8 @@ + @string/auto AES-GCM XChaCha20-Poly1305 - @string/auto