From fe7d3ef7fee6d40eed58c9eb5ddfc450203465cb Mon Sep 17 00:00:00 2001 From: ThomasSession Date: Mon, 9 Sep 2024 16:17:37 +1000 Subject: [PATCH] Cleaning up permissions Accompanist doesn't handle "ask every time" properly so we need to use our old xml methods --- .../securesms/preferences/QRCodeActivity.kt | 6 +++ .../org/thoughtcrime/securesms/ui/Util.kt | 10 +++++ .../securesms/ui/components/QR.kt | 39 +++++++++---------- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt index fbf0affb8c..045b08fcda 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt @@ -25,6 +25,7 @@ import org.session.libsignal.utilities.PublicKeyValidation import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 import org.thoughtcrime.securesms.database.threadDatabase +import org.thoughtcrime.securesms.permissions.Permissions import org.thoughtcrime.securesms.ui.theme.LocalDimensions import org.thoughtcrime.securesms.ui.theme.LocalColors import org.thoughtcrime.securesms.ui.components.QRScannerScreen @@ -68,6 +69,11 @@ class QRCodeActivity : PassphraseRequiredActionBarActivity() { finish() } } + + override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults) + } } @OptIn(ExperimentalFoundationApi::class) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/Util.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/Util.kt index eb8ff4ba3c..22eb4bf860 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/Util.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/Util.kt @@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.ui import android.app.Activity import android.content.Context +import android.content.ContextWrapper import androidx.compose.runtime.Composable import androidx.compose.ui.platform.ComposeView import androidx.fragment.app.Fragment @@ -48,3 +49,12 @@ fun ComposeView.setThemedContent(content: @Composable () -> Unit) = setContent { fun PermissionState.isPermanentlyDenied(): Boolean { return !status.shouldShowRationale && !status.isGranted } + +fun Context.findActivity(): Activity { + var context = this + while (context is ContextWrapper) { + if (context is Activity) return context + context = context.baseContext + } + throw IllegalStateException("Permissions should be called in the context of an Activity") +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/components/QR.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/components/QR.kt index 55af472f68..b8dada1204 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/components/QR.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/components/QR.kt @@ -2,7 +2,9 @@ package org.thoughtcrime.securesms.ui.components import android.Manifest import android.annotation.SuppressLint +import android.app.Activity import android.content.Intent +import android.content.pm.PackageManager import android.net.Uri import android.provider.Settings import androidx.camera.core.CameraSelector @@ -20,7 +22,6 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Scaffold import androidx.compose.material3.Snackbar @@ -46,10 +47,8 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView -import com.google.accompanist.permissions.ExperimentalPermissionsApi -import com.google.accompanist.permissions.isGranted -import com.google.accompanist.permissions.rememberPermissionState -import com.google.accompanist.permissions.shouldShowRationale +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat import com.google.zxing.BinaryBitmap import com.google.zxing.ChecksumException import com.google.zxing.FormatException @@ -59,24 +58,24 @@ import com.google.zxing.Result import com.google.zxing.common.HybridBinarizer import com.google.zxing.qrcode.QRCodeReader import com.squareup.phrase.Phrase -import java.util.concurrent.Executors import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.launch import network.loki.messenger.R import org.session.libsession.utilities.StringSubstitutionConstants.APP_NAME_KEY import org.session.libsignal.utilities.Log +import org.thoughtcrime.securesms.mediasend.MediaSendActivity +import org.thoughtcrime.securesms.permissions.Permissions import org.thoughtcrime.securesms.ui.AlertDialog import org.thoughtcrime.securesms.ui.DialogButtonModel import org.thoughtcrime.securesms.ui.GetString +import org.thoughtcrime.securesms.ui.findActivity import org.thoughtcrime.securesms.ui.getSubbedString -import org.thoughtcrime.securesms.ui.isPermanentlyDenied -import org.thoughtcrime.securesms.ui.theme.LocalColors import org.thoughtcrime.securesms.ui.theme.LocalDimensions import org.thoughtcrime.securesms.ui.theme.LocalType +import java.util.concurrent.Executors private const val TAG = "NewMessageFragment" -@OptIn(ExperimentalPermissionsApi::class) @Composable fun QRScannerScreen( errors: Flow, @@ -93,11 +92,13 @@ fun QRScannerScreen( ) { LocalSoftwareKeyboardController.current?.hide() - val cameraPermissionState = rememberPermissionState(Manifest.permission.CAMERA) + val context = LocalContext.current + val permission = Manifest.permission.CAMERA var showCameraPermissionDialog by remember { mutableStateOf(false) } - if (cameraPermissionState.status.isGranted) { + if (ContextCompat.checkSelfPermission(context, permission) + == PackageManager.PERMISSION_GRANTED) { ScanQrCode(errors, onScan) } else { Column( @@ -120,14 +121,12 @@ fun QRScannerScreen( stringResource(R.string.cameraGrantAccess), modifier = Modifier.fillMaxWidth(), onClick = { - // if the permission has been denied permanently, ask the user to go to the settings - if (cameraPermissionState.isPermanentlyDenied()){ - showCameraPermissionDialog = true - } - // otherwise ask for permission - else { - cameraPermissionState.run { launchPermissionRequest() } - } + Permissions.with(context.findActivity()) + .request(permission) + .withPermanentDenialDialog( + context.getSubbedString(R.string.permissionsCameraDenied, + APP_NAME_KEY to context.getString(R.string.app_name)) + ).execute() } ) Spacer(modifier = Modifier.weight(1f)) @@ -136,8 +135,6 @@ fun QRScannerScreen( // camera permission denied permanently dialog if(showCameraPermissionDialog){ - val context = LocalContext.current - AlertDialog( onDismissRequest = { showCameraPermissionDialog = false }, title = stringResource(R.string.permissionsRequired),