Fix camera-first qr scans.

This commit is contained in:
Michelle Tang 2024-06-07 09:58:14 -07:00 committed by Alex Hart
parent 7086709082
commit baaad0e475
6 changed files with 40 additions and 17 deletions

View file

@ -88,7 +88,7 @@ class LinkDeviceFragment : ComposeFragment() {
Scaffolds.Settings(
title = stringResource(id = R.string.preferences__linked_devices),
onNavigationClick = { navController.popBackStack() },
onNavigationClick = { findNavController().popOrFinish() },
navigationIconPainter = painterResource(id = R.drawable.ic_arrow_left_24),
navigationContentDescription = stringResource(id = R.string.Material3SearchToolbar__close)
) { contentPadding: PaddingValues ->
@ -103,6 +103,12 @@ class LinkDeviceFragment : ComposeFragment() {
)
}
}
private fun NavController.popOrFinish() {
if (!popBackStack()) {
requireActivity().finishAfterTransition()
}
}
}
@Composable
@ -117,7 +123,7 @@ fun DeviceDescriptionScreen(
) {
if (state.progressDialogMessage != -1) {
if (navController?.currentDestination?.id == R.id.linkDeviceFinishedSheet) {
navController?.popBackStack()
navController.popBackStack()
}
Dialogs.IndeterminateProgressDialog(stringResource(id = state.progressDialogMessage))
}

View file

@ -166,7 +166,8 @@ public class CameraXFragment extends LoggingFragment implements CameraFragment {
this.controlsContainer = view.findViewById(R.id.camerax_controls_container);
this.cameraXModePolicy = CameraXModePolicy.acquire(requireContext(),
controller.getMediaConstraints(),
requireArguments().getBoolean(IS_VIDEO_ENABLED, true));
requireArguments().getBoolean(IS_VIDEO_ENABLED, true),
requireArguments().getBoolean(IS_QR_SCAN_ENABLED, false));
this.missingPermissionsContainer = view.findViewById(R.id.missing_permissions_container);
this.missingPermissionsText = view.findViewById(R.id.missing_permissions_text);
this.allowAccessButton = view.findViewById(R.id.allow_access_button);

View file

@ -15,8 +15,18 @@ sealed class CameraXModePolicy {
abstract val isVideoSupported: Boolean
abstract val isQrScanEnabled: Boolean
abstract fun initialize(cameraController: CameraXController)
open fun initialize(cameraController: CameraXController, useCaseFlags: Int) {
if (isQrScanEnabled) {
cameraController.setEnabledUseCases(useCaseFlags or CameraController.IMAGE_ANALYSIS)
} else {
cameraController.setEnabledUseCases(useCaseFlags)
}
}
open fun setToImage(cameraController: CameraXController) = Unit
open fun setToVideo(cameraController: CameraXController) = Unit
@ -24,19 +34,19 @@ sealed class CameraXModePolicy {
/**
* The device supports having Image and Video enabled at the same time
*/
object Mixed : CameraXModePolicy() {
data class Mixed(override val isQrScanEnabled: Boolean) : CameraXModePolicy() {
override val isVideoSupported: Boolean = true
override fun initialize(cameraController: CameraXController) {
cameraController.setEnabledUseCases(CameraController.IMAGE_CAPTURE or CameraController.VIDEO_CAPTURE)
super.initialize(cameraController, CameraController.IMAGE_CAPTURE or CameraController.VIDEO_CAPTURE)
}
}
/**
* The device supports image and video, but only one mode at a time.
*/
object Single : CameraXModePolicy() {
data class Single(override val isQrScanEnabled: Boolean) : CameraXModePolicy() {
override val isVideoSupported: Boolean = true
@ -45,29 +55,29 @@ sealed class CameraXModePolicy {
}
override fun setToImage(cameraController: CameraXController) {
cameraController.setEnabledUseCases(CameraController.IMAGE_CAPTURE)
super.initialize(cameraController, CameraController.IMAGE_CAPTURE)
}
override fun setToVideo(cameraController: CameraXController) {
cameraController.setEnabledUseCases(CameraController.VIDEO_CAPTURE)
super.initialize(cameraController, CameraController.VIDEO_CAPTURE)
}
}
/**
* The device supports taking images only.
*/
object ImageOnly : CameraXModePolicy() {
data class ImageOnly(override val isQrScanEnabled: Boolean) : CameraXModePolicy() {
override val isVideoSupported: Boolean = false
override fun initialize(cameraController: CameraXController) {
cameraController.setEnabledUseCases(CameraController.IMAGE_CAPTURE)
super.initialize(cameraController, CameraController.IMAGE_CAPTURE)
}
}
companion object {
@JvmStatic
fun acquire(context: Context, mediaConstraints: MediaConstraints, isVideoEnabled: Boolean): CameraXModePolicy {
fun acquire(context: Context, mediaConstraints: MediaConstraints, isVideoEnabled: Boolean, isQrScanEnabled: Boolean): CameraXModePolicy {
val isVideoSupported = Build.VERSION.SDK_INT >= 26 &&
isVideoEnabled &&
MediaConstraints.isVideoTranscodeAvailable() &&
@ -79,9 +89,9 @@ sealed class CameraXModePolicy {
!FeatureFlags.cameraXMixedModelBlocklist().asListContains(Build.MODEL)
return when {
isMixedModeSupported -> Mixed
isVideoSupported -> Single
else -> ImageOnly
isMixedModeSupported -> Mixed(isQrScanEnabled)
isVideoSupported -> Single(isQrScanEnabled)
else -> ImageOnly(isQrScanEnabled)
}
}
}

View file

@ -14,6 +14,7 @@ import org.signal.core.util.concurrent.LifecycleDisposable
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.DeviceActivity
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
import org.thoughtcrime.securesms.mediasend.CameraFragment
import org.thoughtcrime.securesms.mediasend.Media
import org.thoughtcrime.securesms.mediasend.v2.HudCommand
@ -23,6 +24,7 @@ import org.thoughtcrime.securesms.mms.MediaConstraints
import org.thoughtcrime.securesms.permissions.Permissions
import org.thoughtcrime.securesms.stories.Stories
import org.thoughtcrime.securesms.util.CommunicationActions
import org.thoughtcrime.securesms.util.FeatureFlags
import org.thoughtcrime.securesms.util.navigation.safeNavigate
import java.io.FileDescriptor
import java.util.Optional
@ -92,7 +94,11 @@ class MediaCaptureFragment : Fragment(R.layout.fragment_container), CameraFragme
.setTitle(R.string.MediaCaptureFragment_device_link_dialog_title)
.setMessage(R.string.MediaCaptureFragment_device_link_dialog_body)
.setPositiveButton(R.string.MediaCaptureFragment_device_link_dialog_continue) { d, _ ->
startActivity(DeviceActivity.getIntentForScanner(requireContext()))
if (FeatureFlags.linkedDevicesV2()) {
startActivity(AppSettingsActivity.linkedDevices(requireContext()))
} else {
startActivity(DeviceActivity.getIntentForScanner(requireContext()))
}
requireActivity().finish()
}
.setNegativeButton(android.R.string.cancel, null)

View file

@ -591,7 +591,7 @@
<action
android:id="@+id/action_direct_to_devices"
app:destination="@id/deviceActivity"
app:destination="@id/linkDeviceFragment"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_close_enter"

View file

@ -591,7 +591,7 @@
<action
android:id="@+id/action_direct_to_devices"
app:destination="@id/deviceActivity"
app:destination="@id/linkDeviceFragment"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:popEnterAnim="@anim/fragment_close_enter"