Repository: wordpress-mobile/WordPress-Android (language: kotlin)

Issue:
RuntimeException: Unable to start activity ComponentInfo{com.jetpack.android/org.wordpress.android.ui.stories.Story...
Sentry Issue: [JETPACK-ANDROID-FBG](https://a8c.sentry.io/issues/4681256402/?referrer=github_integration)

```
ClassNotFoundException: androidx.camera.core.CameraX$LensFacing
    at com.automattic.photoeditor.camera.CameraXBasicHandling.<init>(CameraXBasicHandling.kt:42)
    at com.automattic.photoeditor.camera.CameraXBasicHandling.<clinit>(CameraXBasicHandling.kt:332)
    at com.automattic.photoeditor.state.BackgroundSurfaceManager.addHandlerFragmentOrFindByTag(BackgroundSurfaceManager.kt:363)
    at com.automattic.photoeditor.state.BackgroundSurfaceManager.onCreate(BackgroundSurfaceManager.kt:80)
    at java.lang.reflect.Method.invoke(Method.java)
...
(28 additional frame(s) were not displayed)

NoClassDefFoundError: Failed resolution of: Landroidx/camera/core/CameraX$LensFacing;
    at com.automattic.photoeditor.camera.CameraXBasicHandling.<init>(CameraXBasicHandling.kt:42)
    at com.automattic.photoeditor.camera.CameraXBasicHandling.<clinit>(CameraXBasicHandling.kt:332)
    at com.automattic.photoeditor.state.BackgroundSurfaceManager.addHandlerFragmentOrFindByTag(BackgroundSurfaceManager.kt:363)
    at com.automattic.photoeditor.state.BackgroundSurfaceManager.onCreate(BackgroundSurfaceManager.kt:80)
    at java.lang.reflect.Method.invoke(Method.java)
...
(28 additional frame(s) were not displayed)

RuntimeException: Failed to call observer method
    at androidx.lifecycle.ClassesInfoCache$MethodReference.invokeCallback(ClassesInfoCache.java:232)
    at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeMethodsForEvent(ClassesInfoCache.java:199)
    at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeCallbacks(ClassesInfoCache.java:190)
    at androidx.lifecycle.ReflectiveGenericLifecycleObserver.onStateChanged(ReflectiveGenericLifecycleObserver.java:40)
    at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.kt:314)
...
(23 additional frame(s) were not displayed)

RuntimeException: Unable to start activity ComponentInfo{com.jetpack.android/org.wordpress.android.ui.stories.StoryComposerActivity}: java.lang.RuntimeException: Failed to call observer method
    at android.app.ActivityThread.performLaunchActivity
    at android.app.ActivityThread.handleLaunchActivity
    at android.app.servertransaction.LaunchActivityItem.execute
    at android.app.servertransaction.TransactionExecutor.executeCallbacks
    at android.app.servertransaction.TransactionExecutor.execute
...
(8 additional frame(s) were not displayed)
```


Discussion hints:
I was able to reproduce this crash on in debug mode on a Pixel 5 (Android 14) just by trying to create a new story.
Pasting the full stack trace below:
```
FATAL EXCEPTION: main
Process: com.jetpack.android.beta, PID: 11027
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.jetpack.android.beta/org.wordpress.android.ui.stories.StoryComposerActivity}: java.lang.RuntimeException: Failed to call observer method
	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3782)
	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3922)
	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)
	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2443)
	at android.os.Handler.dispatchMessage(Handler.java:106)
	at android.os.Looper.loopOnce(Looper.java:205)
	at android.os.Looper.loop(Looper.java:294)
	at android.app.ActivityThread.main(ActivityThread.java:8177)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
Caused by: java.lang.RuntimeException: Failed to call observer method
	at androidx.lifecycle.ClassesInfoCache$MethodReference.invokeCallback(ClassesInfoCache.java:232)
	at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeMethodsForEvent(ClassesInfoCache.java:199)
	at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeCallbacks(ClassesInfoCache.java:190)
	at androidx.lifecycle.ReflectiveGenericLifecycleObserver.onStateChanged(ReflectiveGenericLifecycleObserver.java:40)
	at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.kt:314)
	at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.kt:251)
	at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.kt:287)
	at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.kt:136)
	at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.kt:119)
	at androidx.lifecycle.ReportFragment$Companion.dispatch$lifecycle_runtime_release(ReportFragment.kt:192)
	at androidx.lifecycle.ReportFragment$LifecycleCallbacks.onActivityPostCreated(ReportFragment.kt:115)
	at android.app.Activity.dispatchActivityPostCreated(Activity.java:1434)
	at android.app.Activity.performCreate(Activity.java:8606)
	at android.app.Activity.performCreate(Activity.java:8573)
	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1456)
	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3764)
	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3922) 
	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103) 
	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139) 
	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96) 
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2443) 
	at android.os.Handler.dispatchMessage(Handler.java:106) 
	at android.os.Looper.loopOnce(Looper.java:205) 
	at android.os.Looper.loop(Looper.java:294) 
	at android.app.ActivityThread.main(ActivityThread.java:8177) 
	at java.lang.reflect.Method.invoke(Native Method) 
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552) 
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971) 
Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/camera/core/CameraX$LensFacing;
	at com.automattic.photoeditor.camera.CameraXBasicHandling.<init>(CameraXBasicHandling.kt:42)
	at com.automattic.photoeditor.camera.CameraXBasicHandling.<clinit>(CameraXBasicHandling.kt:332)
	at com.automattic.photoeditor.state.BackgroundSurfaceManager.addHandlerFragmentOrFindByTag(BackgroundSurfaceManager.kt:363)
	at com.automattic.photoeditor.state.BackgroundSurfaceManager.onCreate(BackgroundSurfaceManager.kt:80)
	at java.lang.reflect.Method.invoke(Native Method)
	at androidx.lifecycle.ClassesInfoCache$MethodReference.invokeCallback(ClassesInfoCache.java:225)
	at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeMethodsForEvent(ClassesInfoCache.java:199) 
	at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeCallbacks(ClassesInfoCache.java:190) 
	at androidx.lifecycle.ReflectiveGenericLifecycleObserver.onStateChanged(ReflectiveGenericLifecycleObserver.java:40) 
	at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.kt:314) 
	at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.kt:251) 
	at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.kt:287) 
	at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.kt:136) 
	at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.kt:119) 
	at androidx.lifecycle.ReportFragment$Companion.dispatch$lifecycle_runtime_release(ReportFragment.kt:192) 
	at androidx.lifecycle.ReportFragment$LifecycleCallbacks.onActivityPostCreated(ReportFragment.kt:115) 
	at android.app.Activity.dispatchActivityPostCreated(Activity.java:1434) 
	at android.app.Activity.performCreate(Activity.java:8606) 
	at android.app.Activity.performCreate(Activity.java:8573) 
	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1456) 
	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3764) 
	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3922) 
	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103) 
	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139) 
	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96) 
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2443) 
	at android.os.Handler.dispatchMessage(Handler.java:106) 
	at android.os.Looper.loopOnce(Looper.java:205) 
	at android.os.Looper.loop(Looper.java:294) 
	at android.app.ActivityThread.main(ActivityThread.java:8177) 
	at java.lang.reflect.Method.invoke(Native Method) 
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552) 
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971) 
Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.camera.core.CameraX$LensFacing" on path: DexPathList[[zip file "/data/app/~~higr-3bKLIdE8LdnrFU9WA==/com.jetpack.android.beta-mQoXQEgQC6cwj8AEF5jpEw==/base.apk"],nativeLibraryDirectories=[/data/app/~~higr-3bKLIdE8LdnrFU9WA==/com.jetpack.android.beta-mQoXQEgQC6cwj8AEF5jpEw==/lib/arm64, /data/app/~~higr-3bKLIdE8LdnrFU9WA==/com.jetpack.android.beta-mQoXQEgQC6cwj8AEF5jpEw==/base.apk!/lib/arm64-v8a, /system/lib64, /system_ext/lib64]]
	at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
```
I spent some time investigating this. My understanding is that the crash occurs because [the stories-android library uses an older version (`1.0.0-alpha06`) of the `androidx.camera library`](https://github.com/Automattic/stories-android/blob/trunk/build.gradle#L99) than the one we introduced (`1.2.3`) in the project with https://github.com/wordpress-mobile/WordPress-Android/pull/19637.
I tried excluding like:
```
    implementation ("$gradle.ext.storiesAndroidPath:$automatticStoriesVersion") {
...
        exclude group: 'androidx.camera', module: 'camera-camera2'
    }
```
but this doesn't work since the main app library is newer and is used by default.
Reverting #19637 will cause a regression of https://github.com/wordpress-mobile/WordPress-Android/issues/18785.
Upgrading the `stories-android` seems like the proper way forward but it would require more effort and might cause breakages on other apps using the library.


@antonis - I've exhausted my resources for a "gradle" solution. We have two options
1 - Revert the PR - which probably needs to be done without a proper revert command because all of the string have been updated already. :(
2 - Update `stories-android` to use `cameraX` 1.2.3. 

There are rumblings that tumblr uses `stories-android` and I'm not sure if that would prohibit an update. Once I find out the answer to this, then I can decide on a way forward. 
@antonis Thinking out loud -- is there anything stopping us from releasing a new version of the `stories-android` library that we use in Jetpack? Tumblr does not need to upgrade their version of the library until they are ready? wdyt? I'd like to go down this route rather than having a poor scanning experience in JP.

Pull request: QR Code: Partial MLKit Revert
Fixes #19695 

This PR reverts the use of MLKit for scanning QR Code as used by the web login. The reason for the revert is because the `stories-android` has a dependency on camerax `1.0.0-alpha06' and the MLKit needs at least version '1.2.3'. We could not resolve the dependency via gradle :(.

The entire `barcodescanner` package had to be removed because the dependencies were nixed from build.gradle. Since the strings were already translated, I marked the resource as unused so they would not have to go through translation again.

The plan is to update the `stories-android` to CameraX version `1.2.3` during the next hack week

cc: @oguzkocer 

## To Test:
Story Post
- Install the JP app build from this PR
- Navigate to My Site
- Tap on the FAB and select Story Post
- Navigate past the intro (if shown) and agree to any permissions
- Tap the "camera" icon
- ✅ Verify the camera launches and the app doesn't crash

[JP] Scan Login Code - Success
- Log in to the Jetpack app with a WP.com account (note that you need to use a non A8C account and a non 2FA enabled account).
- Navigate to the Me screen (click on bottom Me navigation tab).
(STOP)
- Head over to your desktop and open a web browser (note that using an incognito tab works best).
- Browse to wordpress.com (note that if you are logged-in, log-out first).
- Tap the Log In link (top-right).
- Tap the Login via the mobile app link in the list of options below the main Continue button (bottom-middle).
- Verify you are on the Login via the mobile app view and Use QR Code to login is shown, along with a QR code for you to scan.

## Regression Notes

1. Potential unintended areas of impact
Stories still crash when launching camera

2. What I did to test those areas of impact (or what existing automated tests I relied on)
Manual testing

3. What automated tests I added (or what prevented me from doing so)
N/A

-----

## PR Submission Checklist:

- [X] I have completed the Regression Notes.
- [X] I have considered adding accessibility improvements for my changes.
- [X] I have considered if this change warrants user-facing release notes and have added them to `RELEASE-NOTES.txt` if necessary.

-----

## UI Changes Testing Checklist: N/A


Test command: ./gradlew :WordPress:testWordpressVanillaDebugUnitTest --tests "org.wordpress.android.ui.qrcodeauth.QRCodeAuthViewModelTest"

Fix patch:
diff --git a/WordPress/build.gradle b/WordPress/build.gradle
index 0b810da286a3..a52831f4e084 100644
--- a/WordPress/build.gradle
+++ b/WordPress/build.gradle
@@ -420,14 +420,8 @@ dependencies {
     implementation "androidx.lifecycle:lifecycle-process:$androidxLifecycleVersion"
     implementation "com.android.volley:volley:$androidVolleyVersion"
     implementation "com.google.android.gms:play-services-auth:$googlePlayServicesAuthVersion"
+    implementation "com.google.android.gms:play-services-code-scanner:$googlePlayServicesCodeScannerVersion"
     implementation "com.google.mlkit:barcode-scanning-common:$googleMLKitBarcodeScanningVersion"
-    implementation "com.google.mlkit:text-recognition:$mlkitTextRecognitionVersion"
-    implementation "com.google.mlkit:barcode-scanning:$mlkitBarcodeScanningVersion"
-
-    // CameraX
-    implementation "androidx.camera:camera-camera2:$androidxCameraVersion"
-    implementation "androidx.camera:camera-lifecycle:$androidxCameraVersion"
-    implementation "androidx.camera:camera-view:$androidxCameraVersion"
 
     implementation "com.android.installreferrer:installreferrer:$androidInstallReferrerVersion"
     implementation "com.github.chrisbanes:PhotoView:$chrisbanesPhotoviewVersion"
diff --git a/WordPress/src/main/java/org/wordpress/android/modules/CodeScannerModule.kt b/WordPress/src/main/java/org/wordpress/android/modules/CodeScannerModule.kt
deleted file mode 100644
index 4584657f8a11..000000000000
--- a/WordPress/src/main/java/org/wordpress/android/modules/CodeScannerModule.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.wordpress.android.modules
-
-import com.google.mlkit.vision.barcode.BarcodeScanner
-import com.google.mlkit.vision.barcode.BarcodeScanning
-import dagger.Module
-import dagger.Provides
-import dagger.Reusable
-import dagger.hilt.InstallIn
-import dagger.hilt.components.SingletonComponent
-import org.wordpress.android.ui.barcodescanner.CodeScanner
-import org.wordpress.android.ui.barcodescanner.GoogleBarcodeFormatMapper
-import org.wordpress.android.ui.barcodescanner.GoogleCodeScannerErrorMapper
-import org.wordpress.android.ui.barcodescanner.GoogleMLKitCodeScanner
-import org.wordpress.android.ui.barcodescanner.MediaImageProvider
-
-@InstallIn(SingletonComponent::class)
-@Module
-class CodeScannerModule {
-    @Provides
-    @Reusable
-    fun provideGoogleCodeScanner(
-        barcodeScanner: BarcodeScanner,
-        googleCodeScannerErrorMapper: GoogleCodeScannerErrorMapper,
-        barcodeFormatMapper: GoogleBarcodeFormatMapper,
-        inputImageProvider: MediaImageProvider,
-    ): CodeScanner {
-        return GoogleMLKitCodeScanner(
-            barcodeScanner,
-            googleCodeScannerErrorMapper,
-            barcodeFormatMapper,
-            inputImageProvider,
-        )
-    }
-
-    @Provides
-    @Reusable
-    fun providesGoogleBarcodeScanner() = BarcodeScanning.getClient()
-}
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScanner.kt b/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScanner.kt
deleted file mode 100644
index e5df791ee239..000000000000
--- a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScanner.kt
+++ /dev/null
@@ -1,99 +0,0 @@
-package org.wordpress.android.ui.barcodescanner
-
-import android.content.res.Configuration
-import android.util.Size
-import androidx.camera.core.CameraSelector
-import androidx.camera.core.ImageAnalysis
-import androidx.camera.core.ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST
-import androidx.camera.core.ImageProxy
-import androidx.camera.lifecycle.ProcessCameraProvider
-import androidx.camera.view.PreviewView
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.LocalLifecycleOwner
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.viewinterop.AndroidView
-import androidx.core.content.ContextCompat
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.flowOf
-import org.wordpress.android.ui.compose.theme.AppTheme
-import androidx.camera.core.Preview as CameraPreview
-
-@Composable
-fun BarcodeScanner(
-    codeScanner: CodeScanner,
-    onScannedResult: (Flow<CodeScannerStatus>) -> Unit
-) {
-    val context = LocalContext.current
-    val lifecycleOwner = LocalLifecycleOwner.current
-    val cameraProviderFuture = remember {
-        ProcessCameraProvider.getInstance(context)
-    }
-    Column(
-        modifier = Modifier.fillMaxSize()
-    ) {
-        AndroidView(
-            factory = { context ->
-                val previewView = PreviewView(context)
-                val preview = CameraPreview.Builder().build()
-                preview.setSurfaceProvider(previewView.surfaceProvider)
-                val selector = CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build()
-                val imageAnalysis = ImageAnalysis.Builder().setTargetResolution(
-                    Size(
-                        previewView.width,
-                        previewView.height
-                    )
-                )
-                    .setBackpressureStrategy(STRATEGY_KEEP_ONLY_LATEST)
-                    .build()
-                imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(context)) { imageProxy ->
-                    onScannedResult(codeScanner.startScan(imageProxy))
-                }
-                try {
-                    cameraProviderFuture.get().bindToLifecycle(lifecycleOwner, selector, preview, imageAnalysis)
-                } catch (e: IllegalStateException) {
-                    onScannedResult(
-                        flowOf(
-                            CodeScannerStatus.Failure(
-                                e.message
-                                    ?: "Illegal state exception while binding camera provider to lifecycle",
-                                CodeScanningErrorType.Other(e)
-                            )
-                        )
-                    )
-                } catch (e: IllegalArgumentException) {
-                    onScannedResult(
-                        flowOf(
-                            CodeScannerStatus.Failure(
-                                e.message
-                                    ?: "Illegal argument exception while binding camera provider to lifecycle",
-                                CodeScanningErrorType.Other(e)
-                            )
-                        )
-                    )
-                }
-                previewView
-            },
-            modifier = Modifier.fillMaxSize()
-        )
-    }
-}
-
-class DummyCodeScanner : CodeScanner {
-    override fun startScan(imageProxy: ImageProxy): Flow<CodeScannerStatus> {
-        return flowOf(CodeScannerStatus.Success("", GoogleBarcodeFormatMapper.BarcodeFormat.FormatUPCA))
-    }
-}
-
-@Preview(name = "Light mode")
-@Preview(name = "Dark mode", uiMode = Configuration.UI_MODE_NIGHT_YES)
-@Composable
-private fun BarcodeScannerScreenPreview() {
-    AppTheme {
-        BarcodeScanner(codeScanner = DummyCodeScanner(), onScannedResult = {})
-    }
-}
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScannerScreen.kt b/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScannerScreen.kt
deleted file mode 100644
index 01a270db9ece..000000000000
--- a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScannerScreen.kt
+++ /dev/null
@@ -1,146 +0,0 @@
-package org.wordpress.android.ui.barcodescanner
-
-import android.content.res.Configuration
-import androidx.activity.compose.rememberLauncherForActivityResult
-import androidx.activity.result.contract.ActivityResultContracts
-import androidx.compose.foundation.layout.padding
-import androidx.compose.material.AlertDialog
-import androidx.compose.material.MaterialTheme
-import androidx.compose.material.Text
-import androidx.compose.material.TextButton
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.dp
-import org.wordpress.android.R
-import kotlinx.coroutines.flow.Flow
-import org.wordpress.android.ui.compose.theme.AppTheme
-
-@Composable
-fun BarcodeScannerScreen(
-    codeScanner: CodeScanner,
-    permissionState: BarcodeScanningViewModel.PermissionState,
-    onResult: (Boolean) -> Unit,
-    onScannedResult: (Flow<CodeScannerStatus>) -> Unit,
-) {
-    val cameraPermissionLauncher = rememberLauncherForActivityResult(
-        contract = ActivityResultContracts.RequestPermission(),
-        onResult = { granted ->
-            onResult(granted)
-        },
-    )
-    LaunchedEffect(key1 = Unit) {
-        cameraPermissionLauncher.launch(BarcodeScanningFragment.KEY_CAMERA_PERMISSION)
-    }
-    when (permissionState) {
-        BarcodeScanningViewModel.PermissionState.Granted -> {
-            BarcodeScanner(
-                codeScanner = codeScanner,
-                onScannedResult = onScannedResult
-            )
-        }
-        is BarcodeScanningViewModel.PermissionState.ShouldShowRationale -> {
-            AlertDialog(
-                title = stringResource(id = permissionState.title),
-                message = stringResource(id = permissionState.message),
-                ctaLabel = stringResource(id = permissionState.ctaLabel),
-                dismissCtaLabel = stringResource(id = permissionState.dismissCtaLabel),
-                ctaAction = { permissionState.ctaAction.invoke(cameraPermissionLauncher) },
-                dismissCtaAction = { permissionState.dismissCtaAction.invoke() }
-            )
-        }
-        is BarcodeScanningViewModel.PermissionState.PermanentlyDenied -> {
-            AlertDialog(
-                title = stringResource(id = permissionState.title),
-                message = stringResource(id = permissionState.message),
-                ctaLabel = stringResource(id = permissionState.ctaLabel),
-                dismissCtaLabel = stringResource(id = permissionState.dismissCtaLabel),
-                ctaAction = { permissionState.ctaAction.invoke(cameraPermissionLauncher) },
-                dismissCtaAction = { permissionState.dismissCtaAction.invoke() }
-            )
-        }
-        BarcodeScanningViewModel.PermissionState.Unknown -> {
-            // no-op
-        }
-    }
-}
-
-@Composable
-private fun AlertDialog(
-    title: String,
-    message: String,
-    ctaLabel: String,
-    dismissCtaLabel: String,
-    ctaAction: () -> Unit,
-    dismissCtaAction: () -> Unit,
-) {
-    AlertDialog(
-        onDismissRequest = { dismissCtaAction() },
-        title = {
-            Text(title)
-        },
-        text = {
-            Text(message)
-        },
-        confirmButton = {
-            TextButton(
-                onClick = {
-                    ctaAction()
-                }
-            ) {
-                Text(
-                    ctaLabel,
-                    color = MaterialTheme.colors.secondary,
-                    modifier = Modifier.padding(8.dp)
-                )
-            }
-        },
-        dismissButton = {
-            TextButton(
-                onClick = {
-                    dismissCtaAction()
-                }
-            ) {
-                Text(
-                    dismissCtaLabel,
-                    color = MaterialTheme.colors.secondary,
-                    modifier = Modifier.padding(8.dp)
-                )
-            }
-        },
-    )
-}
-
-@Preview(name = "Light mode")
-@Preview(name = "Dark mode", uiMode = Configuration.UI_MODE_NIGHT_YES)
-@Composable
-fun DeniedOnceAlertDialog() {
-    AppTheme {
-        AlertDialog(
-            title = stringResource(id = R.string.barcode_scanning_alert_dialog_title),
-            message = stringResource(id = R.string.barcode_scanning_alert_dialog_rationale_message),
-            ctaLabel = stringResource(id = R.string.barcode_scanning_alert_dialog_rationale_cta_label),
-            dismissCtaLabel = stringResource(id = R.string.barcode_scanning_alert_dialog_dismiss_label),
-            ctaAction = {},
-            dismissCtaAction = {},
-        )
-    }
-}
-
-@Preview(name = "Light mode")
-@Preview(name = "Dark mode", uiMode = Configuration.UI_MODE_NIGHT_YES)
-@Composable
-fun DeniedPermanentlyAlertDialog() {
-    AppTheme {
-        AlertDialog(
-            title = stringResource(id = R.string.barcode_scanning_alert_dialog_title),
-            message = stringResource(id = R.string.barcode_scanning_alert_dialog_permanently_denied_message),
-            ctaLabel = stringResource(id = R.string.barcode_scanning_alert_dialog_permanently_denied_cta_label),
-            dismissCtaLabel = stringResource(id = R.string.barcode_scanning_alert_dialog_dismiss_label),
-            ctaAction = {},
-            dismissCtaAction = {},
-        )
-    }
-}
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScanningFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScanningFragment.kt
deleted file mode 100644
index a05fd7c67769..000000000000
--- a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScanningFragment.kt
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.wordpress.android.ui.barcodescanner
-
-import android.Manifest
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.activity.addCallback
-import androidx.compose.ui.platform.ComposeView
-import androidx.compose.ui.platform.ViewCompositionStrategy
-import androidx.core.os.bundleOf
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.setFragmentResult
-import androidx.fragment.app.viewModels
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.lifecycleScope
-import androidx.lifecycle.repeatOnLifecycle
-import dagger.hilt.android.AndroidEntryPoint
-import kotlinx.coroutines.launch
-import org.wordpress.android.ui.compose.theme.AppTheme
-import org.wordpress.android.util.WPPermissionUtils
-import javax.inject.Inject
-
-@AndroidEntryPoint
-class BarcodeScanningFragment : Fragment() {
-    private val viewModel: BarcodeScanningViewModel by viewModels()
-
-    @Inject
-    lateinit var codeScanner: GoogleMLKitCodeScanner
-
-    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) =
-        ComposeView(requireContext())
-
-    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-        view as ComposeView
-        view.setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
-        observeCameraPermissionState(view)
-        observeViewModelEvents()
-        initBackPressHandler()
-    }
-
-    private fun observeCameraPermissionState(view: ComposeView) {
-        viewModel.permissionState.observe(viewLifecycleOwner) { permissionState ->
-            view.setContent {
-                AppTheme {
-                    BarcodeScannerScreen(
-                        codeScanner = codeScanner,
-                        permissionState = permissionState,
-                        onResult = { granted ->
-                            viewModel.updatePermissionState(
-                                granted,
-                                shouldShowRequestPermissionRationale(KEY_CAMERA_PERMISSION)
-                            )
-                        },
-                        onScannedResult = { codeScannerStatus ->
-                            viewLifecycleOwner.lifecycleScope.launch {
-                                viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.CREATED) {
-                                    codeScannerStatus.collect { status ->
-                                        setResultAndPopStack(status)
-                                    }
-                                }
-                            }
-                        },
-                    )
-                }
-            }
-        }
-    }
-    private fun observeViewModelEvents() {
-        viewModel.event.observe(viewLifecycleOwner) { event ->
-            when (event) {
-                is BarcodeScanningViewModel.ScanningEvents.LaunchCameraPermission -> {
-                    event.cameraLauncher.launch(KEY_CAMERA_PERMISSION)
-                }
-
-                is BarcodeScanningViewModel.ScanningEvents.OpenAppSettings -> {
-                    WPPermissionUtils.showAppSettings(requireContext())
-                }
-
-                is BarcodeScanningViewModel.ScanningEvents.Exit -> {
-                    setResultAndPopStack(CodeScannerStatus.Exit)
-                }
-            }
-        }
-    }
-
-    private fun initBackPressHandler() {
-        requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
-            setResultAndPopStack(CodeScannerStatus.NavigateUp) }
-    }
-
-    private fun setResultAndPopStack(status: CodeScannerStatus) {
-        setFragmentResult(KEY_BARCODE_SCANNING_REQUEST, bundleOf(KEY_BARCODE_SCANNING_SCAN_STATUS to status))
-        requireActivity().supportFragmentManager.popBackStackImmediate()
-    }
-
-    companion object {
-        const val KEY_BARCODE_SCANNING_SCAN_STATUS = "barcode_scanning_scan_status"
-        const val KEY_BARCODE_SCANNING_REQUEST = "key_barcode_scanning_request"
-        const val KEY_CAMERA_PERMISSION = Manifest.permission.CAMERA
-    }
-}
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScanningTracker.kt b/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScanningTracker.kt
deleted file mode 100644
index c6455ddeed40..000000000000
--- a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScanningTracker.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.wordpress.android.ui.barcodescanner
-
-import org.wordpress.android.analytics.AnalyticsTracker
-import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper
-import javax.inject.Inject
-
-class BarcodeScanningTracker @Inject constructor(
-    private val analyticsTrackerWrapper: AnalyticsTrackerWrapper
-) {
-    fun trackScanFailure(source: ScanningSource, type: CodeScanningErrorType) {
-        analyticsTrackerWrapper.track(
-            AnalyticsTracker.Stat.BARCODE_SCANNING_FAILURE,
-            mapOf(
-                KEY_SCANNING_SOURCE to source.source,
-                KEY_SCANNING_FAILURE_REASON to type.toString(),
-            )
-        )
-    }
-
-    fun trackSuccess(source: ScanningSource) {
-        analyticsTrackerWrapper.track(
-            AnalyticsTracker.Stat.BARCODE_SCANNING_SUCCESS,
-            mapOf(
-                KEY_SCANNING_SOURCE to source.source
-            )
-        )
-    }
-
-    companion object {
-        const val KEY_SCANNING_SOURCE = "source"
-        const val KEY_SCANNING_FAILURE_REASON = "scanning_failure_reason"
-    }
-}
-
-enum class ScanningSource(val source: String) {
-    QRCODE_LOGIN("qrcode_login")
-}
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScanningViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScanningViewModel.kt
deleted file mode 100644
index 532bc34f3ccd..000000000000
--- a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/BarcodeScanningViewModel.kt
+++ /dev/null
@@ -1,107 +0,0 @@
-package org.wordpress.android.ui.barcodescanner
-
-import androidx.activity.compose.ManagedActivityResultLauncher
-import androidx.annotation.StringRes
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
-import dagger.hilt.android.lifecycle.HiltViewModel
-import kotlinx.coroutines.CoroutineDispatcher
-import org.wordpress.android.R
-import org.wordpress.android.modules.BG_THREAD
-import org.wordpress.android.viewmodel.ScopedViewModel
-import javax.inject.Inject
-import javax.inject.Named
-
-@HiltViewModel
-class BarcodeScanningViewModel @Inject constructor(
-    @param:Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher
-) : ScopedViewModel(bgDispatcher) {
-    private val _permissionState = MutableLiveData<PermissionState>()
-    val permissionState: LiveData<PermissionState> = _permissionState
-
-    private val _event: MutableLiveData<ScanningEvents> = MutableLiveData()
-    val event: LiveData<ScanningEvents> = _event
-
-    init {
-        _permissionState.value = PermissionState.Unknown
-    }
-
-    fun updatePermissionState(
-        isPermissionGranted: Boolean,
-        shouldShowRequestPermissionRationale: Boolean,
-    ) {
-        when {
-            isPermissionGranted -> {
-                // display scanning screen
-                _permissionState.value = PermissionState.Granted
-            }
-
-            // It will launch events that some place can response to
-            shouldShowRequestPermissionRationale -> {
-                // Denied once, ask to grant camera permission
-                _permissionState.value = PermissionState.ShouldShowRationale(
-                    title = R.string.barcode_scanning_alert_dialog_title,
-                    message = R.string.barcode_scanning_alert_dialog_rationale_message,
-                    ctaLabel = R.string.barcode_scanning_alert_dialog_rationale_cta_label,
-                    dismissCtaLabel = R.string.barcode_scanning_alert_dialog_dismiss_label,
-                    ctaAction = {  _event.value = ScanningEvents.LaunchCameraPermission(it) },
-                    dismissCtaAction = {
-                        _event.value = (ScanningEvents.Exit)
-                    }
-                )
-            }
-
-            else -> {
-                // Permanently denied, ask to enable permission from the app settings
-                _permissionState.value = PermissionState.PermanentlyDenied(
-                    title = R.string.barcode_scanning_alert_dialog_title,
-                    message = R.string.barcode_scanning_alert_dialog_permanently_denied_message,
-                    ctaLabel = R.string.barcode_scanning_alert_dialog_permanently_denied_cta_label,
-                    dismissCtaLabel = R.string.barcode_scanning_alert_dialog_dismiss_label,
-                    ctaAction = {
-                        _event.value = ScanningEvents.OpenAppSettings(it)
-                    },
-                    dismissCtaAction = {
-                        _event.value = (ScanningEvents.Exit)
-                    }
-                )
-            }
-        }
-    }
-
-    sealed class ScanningEvents {
-        data class LaunchCameraPermission(
-            val cameraLauncher: ManagedActivityResultLauncher<String, Boolean>
-        ) : ScanningEvents()
-
-        data class OpenAppSettings(
-            val cameraLauncher: ManagedActivityResultLauncher<String, Boolean>
-        ) : ScanningEvents()
-
-        object Exit : ScanningEvents()
-    }
-
-    sealed class PermissionState {
-        object Granted : PermissionState()
-
-        data class ShouldShowRationale(
-            @StringRes val title: Int,
-            @StringRes val message: Int,
-            @StringRes val ctaLabel: Int,
-            @StringRes val dismissCtaLabel: Int,
-            val ctaAction: (ManagedActivityResultLauncher<String, Boolean>) -> Unit,
-            val dismissCtaAction: () -> Unit,
-        ) : PermissionState()
-
-        data class PermanentlyDenied(
-            @StringRes val title: Int,
-            @StringRes val message: Int,
-            @StringRes val ctaLabel: Int,
-            @StringRes val dismissCtaLabel: Int,
-            val ctaAction: (ManagedActivityResultLauncher<String, Boolean>) -> Unit,
-            val dismissCtaAction: () -> Unit,
-        ) : PermissionState()
-
-        object Unknown : PermissionState()
-    }
-}
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/CodeScanner.kt b/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/CodeScanner.kt
deleted file mode 100644
index 085841613128..000000000000
--- a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/CodeScanner.kt
+++ /dev/null
@@ -1,93 +0,0 @@
-package org.wordpress.android.ui.barcodescanner
-
-import android.os.Parcelable
-import androidx.camera.core.ImageProxy
-import kotlinx.coroutines.flow.Flow
-import kotlinx.parcelize.Parcelize
-
-interface CodeScanner {
-    fun startScan(imageProxy: ImageProxy): Flow<CodeScannerStatus>
-}
-
-sealed class CodeScannerStatus : Parcelable {
-    @Parcelize
-    data class Success(val code: String, val format: GoogleBarcodeFormatMapper.BarcodeFormat) : CodeScannerStatus()
-    @Parcelize
-    data class Failure(
-        val error: String?,
-        val type: CodeScanningErrorType
-    ) : CodeScannerStatus()
-    @Parcelize
-    data object NavigateUp : CodeScannerStatus()
-    @Parcelize
-    data object Exit : CodeScannerStatus()
-}
-
-sealed class CodeScanningErrorType : Parcelable {
-    @Parcelize
-    object Aborted : CodeScanningErrorType()
-    @Parcelize
-    object AlreadyExists : CodeScanningErrorType()
-    @Parcelize
-    object Cancelled : CodeScanningErrorType()
-    @Parcelize
-    object CodeScannerAppNameUnavailable : CodeScanningErrorType()
-    @Parcelize
-    object CodeScannerCameraPermissionNotGranted : CodeScanningErrorType()
-    @Parcelize
-    object CodeScannerCancelled : CodeScanningErrorType()
-    @Parcelize
-    object CodeScannerGooglePlayServicesVersionTooOld : CodeScanningErrorType()
-    @Parcelize
-    object CodeScannerPipelineInferenceError : CodeScanningErrorType()
-    @Parcelize
-    object CodeScannerPipelineInitializationError : CodeScanningErrorType()
-    @Parcelize
-    object CodeScannerTaskInProgress : CodeScanningErrorType()
-    @Parcelize
-    object CodeScannerUnavailable : CodeScanningErrorType()
-    @Parcelize
-    object DataLoss : CodeScanningErrorType()
-    @Parcelize
-    object DeadlineExceeded : CodeScanningErrorType()
-    @Parcelize
-    object FailedPrecondition : CodeScanningErrorType()
-    @Parcelize
-    object Internal : CodeScanningErrorType()
-    @Parcelize
-    object InvalidArgument : CodeScanningErrorType()
-    @Parcelize
-    object ModelHashMismatch : CodeScanningErrorType()
-    @Parcelize
-    object ModelIncompatibleWithTFLite : CodeScanningErrorType()
-    @Parcelize
-    object NetworkIssue : CodeScanningErrorType()
-    @Parcelize
-    object NotEnoughSpace : CodeScanningErrorType()
-    @Parcelize
-    object NotFound : CodeScanningErrorType()
-    @Parcelize
-    object OutOfRange : CodeScanningErrorType()
-    @Parcelize
-    object PermissionDenied : CodeScanningErrorType()
-    @Parcelize
-    object ResourceExhausted : CodeScanningErrorType()
-    @Parcelize
-    object UnAuthenticated : CodeScanningErrorType()
-    @Parcelize
-    object UnAvailable : CodeScanningErrorType()
-    @Parcelize
-    object UnImplemented : CodeScanningErrorType()
-    @Parcelize
-    object Unknown : CodeScanningErrorType()
-    @Parcelize
-    data class Other(val throwable: Throwable?) : CodeScanningErrorType()
-
-    override fun toString(): String = when (this) {
-        is Other -> this.throwable?.message ?: "Other"
-        else -> this.javaClass.run {
-            name.removePrefix("${`package`?.name ?: ""}.")
-        }
-    }
-}
-
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/GoogleBarcodeFormatMapper.kt b/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/GoogleBarcodeFormatMapper.kt
deleted file mode 100644
index ef7f9973f399..000000000000
--- a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/GoogleBarcodeFormatMapper.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.wordpress.android.ui.barcodescanner
-
-import android.os.Parcelable
-import kotlinx.parcelize.Parcelize
-import javax.inject.Inject
-import com.google.mlkit.vision.barcode.common.Barcode as GoogleBarcode
-
-class GoogleBarcodeFormatMapper @Inject constructor() {
-    @Suppress("ComplexMethod")
-    fun mapBarcodeFormat(format: Int): BarcodeFormat {
-        return when (format) {
-            GoogleBarcode.FORMAT_AZTEC -> BarcodeFormat.FormatAztec
-            GoogleBarcode.FORMAT_CODABAR -> BarcodeFormat.FormatCodaBar
-            GoogleBarcode.FORMAT_CODE_128 -> BarcodeFormat.FormatCode128
-            GoogleBarcode.FORMAT_CODE_39 -> BarcodeFormat.FormatCode39
-            GoogleBarcode.FORMAT_CODE_93 -> BarcodeFormat.FormatCode93
-            GoogleBarcode.FORMAT_DATA_MATRIX -> BarcodeFormat.FormatDataMatrix
-            GoogleBarcode.FORMAT_EAN_13 -> BarcodeFormat.FormatEAN13
-            GoogleBarcode.FORMAT_EAN_8 -> BarcodeFormat.FormatEAN8
-            GoogleBarcode.FORMAT_ITF -> BarcodeFormat.FormatITF
-            GoogleBarcode.FORMAT_PDF417 -> BarcodeFormat.FormatPDF417
-            GoogleBarcode.FORMAT_QR_CODE -> BarcodeFormat.FormatQRCode
-            GoogleBarcode.FORMAT_UPC_A -> BarcodeFormat.FormatUPCA
-            GoogleBarcode.FORMAT_UPC_E -> BarcodeFormat.FormatUPCE
-            GoogleBarcode.FORMAT_UNKNOWN -> BarcodeFormat.FormatUnknown
-            else -> BarcodeFormat.FormatUnknown
-        }
-    }
-
-    sealed class BarcodeFormat(val formatName: String) : Parcelable {
-        @Parcelize
-        object FormatAztec : BarcodeFormat("aztec")
-        @Parcelize
-        object FormatCodaBar : BarcodeFormat("codabar")
-        @Parcelize
-        object FormatCode128 : BarcodeFormat("code_128")
-        @Parcelize
-        object FormatCode39 : BarcodeFormat("code_39")
-        @Parcelize
-        object FormatCode93 : BarcodeFormat("code_93")
-        @Parcelize
-        object FormatDataMatrix : BarcodeFormat("data_matrix")
-        @Parcelize
-        object FormatEAN13 : BarcodeFormat("ean_13")
-        @Parcelize
-        object FormatEAN8 : BarcodeFormat("ean_8")
-        @Parcelize
-        object FormatITF : BarcodeFormat("itf")
-        @Parcelize
-        object FormatPDF417 : BarcodeFormat("pdf_417")
-        @Parcelize
-        object FormatQRCode : BarcodeFormat("qr_code")
-        @Parcelize
-        object FormatUPCA : BarcodeFormat("upc_a")
-        @Parcelize
-        object FormatUPCE : BarcodeFormat("upc_e")
-        @Parcelize
-        object FormatUnknown : BarcodeFormat("unknown")
-    }
-}
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/GoogleCodeScannerErrorMapper.kt b/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/GoogleCodeScannerErrorMapper.kt
deleted file mode 100644
index 983a00300d7b..000000000000
--- a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/GoogleCodeScannerErrorMapper.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.wordpress.android.ui.barcodescanner
-
-import com.google.mlkit.common.MlKitException
-import com.google.mlkit.common.MlKitException.ABORTED
-import com.google.mlkit.common.MlKitException.ALREADY_EXISTS
-import com.google.mlkit.common.MlKitException.CANCELLED
-import com.google.mlkit.common.MlKitException.CODE_SCANNER_APP_NAME_UNAVAILABLE
-import com.google.mlkit.common.MlKitException.CODE_SCANNER_CAMERA_PERMISSION_NOT_GRANTED
-import com.google.mlkit.common.MlKitException.CODE_SCANNER_CANCELLED
-import com.google.mlkit.common.MlKitException.CODE_SCANNER_GOOGLE_PLAY_SERVICES_VERSION_TOO_OLD
-import com.google.mlkit.common.MlKitException.CODE_SCANNER_PIPELINE_INFERENCE_ERROR
-import com.google.mlkit.common.MlKitException.CODE_SCANNER_PIPELINE_INITIALIZATION_ERROR
-import com.google.mlkit.common.MlKitException.CODE_SCANNER_TASK_IN_PROGRESS
-import com.google.mlkit.common.MlKitException.CODE_SCANNER_UNAVAILABLE
-import com.google.mlkit.common.MlKitException.DATA_LOSS
-import com.google.mlkit.common.MlKitException.DEADLINE_EXCEEDED
-import com.google.mlkit.common.MlKitException.FAILED_PRECONDITION
-import com.google.mlkit.common.MlKitException.INTERNAL
-import com.google.mlkit.common.MlKitException.INVALID_ARGUMENT
-import com.google.mlkit.common.MlKitException.MODEL_HASH_MISMATCH
-import com.google.mlkit.common.MlKitException.MODEL_INCOMPATIBLE_WITH_TFLITE
-import com.google.mlkit.common.MlKitException.NETWORK_ISSUE
-import com.google.mlkit.common.MlKitException.NOT_ENOUGH_SPACE
-import com.google.mlkit.common.MlKitException.NOT_FOUND
-import com.google.mlkit.common.MlKitException.OUT_OF_RANGE
-import com.google.mlkit.common.MlKitException.PERMISSION_DENIED
-import com.google.mlkit.common.MlKitException.RESOURCE_EXHAUSTED
-import com.google.mlkit.common.MlKitException.UNAUTHENTICATED
-import com.google.mlkit.common.MlKitException.UNAVAILABLE
-import com.google.mlkit.common.MlKitException.UNIMPLEMENTED
-import com.google.mlkit.common.MlKitException.UNKNOWN
-import javax.inject.Inject
-
-class GoogleCodeScannerErrorMapper @Inject constructor() {
-    @Suppress("ComplexMethod")
-    fun mapGoogleMLKitScanningErrors(
-        exception: Throwable?
-    ): CodeScanningErrorType {
-        return when ((exception as? MlKitException)?.errorCode) {
-            ABORTED -> CodeScanningErrorType.Aborted
-            ALREADY_EXISTS -> CodeScanningErrorType.AlreadyExists
-            CANCELLED -> CodeScanningErrorType.Cancelled
-            CODE_SCANNER_APP_NAME_UNAVAILABLE -> CodeScanningErrorType.CodeScannerAppNameUnavailable
-            CODE_SCANNER_CAMERA_PERMISSION_NOT_GRANTED ->
-                CodeScanningErrorType.CodeScannerCameraPermissionNotGranted
-            CODE_SCANNER_CANCELLED -> CodeScanningErrorType.CodeScannerCancelled
-            CODE_SCANNER_GOOGLE_PLAY_SERVICES_VERSION_TOO_OLD ->
-                CodeScanningErrorType.CodeScannerGooglePlayServicesVersionTooOld
-            CODE_SCANNER_PIPELINE_INFERENCE_ERROR -> CodeScanningErrorType.CodeScannerPipelineInferenceError
-            CODE_SCANNER_PIPELINE_INITIALIZATION_ERROR ->
-                CodeScanningErrorType.CodeScannerPipelineInitializationError
-            CODE_SCANNER_TASK_IN_PROGRESS -> CodeScanningErrorType.CodeScannerTaskInProgress
-            CODE_SCANNER_UNAVAILABLE -> CodeScanningErrorType.CodeScannerUnavailable
-            DATA_LOSS -> CodeScanningErrorType.DataLoss
-            DEADLINE_EXCEEDED -> CodeScanningErrorType.DeadlineExceeded
-            FAILED_PRECONDITION -> CodeScanningErrorType.FailedPrecondition
-            INTERNAL -> CodeScanningErrorType.Internal
-            INVALID_ARGUMENT -> CodeScanningErrorType.InvalidArgument
-            MODEL_HASH_MISMATCH -> CodeScanningErrorType.ModelHashMismatch
-            MODEL_INCOMPATIBLE_WITH_TFLITE -> CodeScanningErrorType.ModelIncompatibleWithTFLite
-            NETWORK_ISSUE -> CodeScanningErrorType.NetworkIssue
-            NOT_ENOUGH_SPACE -> CodeScanningErrorType.NotEnoughSpace
-            NOT_FOUND -> CodeScanningErrorType.NotFound
-            OUT_OF_RANGE -> CodeScanningErrorType.OutOfRange
-            PERMISSION_DENIED -> CodeScanningErrorType.PermissionDenied
-            RESOURCE_EXHAUSTED -> CodeScanningErrorType.ResourceExhausted
-            UNAUTHENTICATED -> CodeScanningErrorType.UnAuthenticated
-            UNAVAILABLE -> CodeScanningErrorType.UnAvailable
-            UNIMPLEMENTED -> CodeScanningErrorType.UnImplemented
-            UNKNOWN -> CodeScanningErrorType.Unknown
-            else -> CodeScanningErrorType.Other(exception)
-        }
-    }
-}
-
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/GoogleMLKitCodeScanner.kt b/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/GoogleMLKitCodeScanner.kt
deleted file mode 100644
index 2e0d339c473e..000000000000
--- a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/GoogleMLKitCodeScanner.kt
+++ /dev/null
@@ -1,70 +0,0 @@
-package org.wordpress.android.ui.barcodescanner
-
-import androidx.camera.core.ImageProxy
-import com.google.mlkit.vision.barcode.BarcodeScanner
-import com.google.mlkit.vision.barcode.common.Barcode
-import kotlinx.coroutines.channels.ProducerScope
-import kotlinx.coroutines.channels.awaitClose
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.callbackFlow
-import javax.inject.Inject
-
-class GoogleMLKitCodeScanner @Inject constructor(
-    private val barcodeScanner: BarcodeScanner,
-    private val errorMapper: GoogleCodeScannerErrorMapper,
-    private val barcodeFormatMapper: GoogleBarcodeFormatMapper,
-    private val inputImageProvider: MediaImageProvider,
-) : CodeScanner {
-    private var barcodeFound = false
-    @androidx.camera.core.ExperimentalGetImage
-    override fun startScan(imageProxy: ImageProxy): Flow<CodeScannerStatus> {
-        return callbackFlow {
-            val barcodeTask = barcodeScanner.process(inputImageProvider.provideImage(imageProxy))
-            barcodeTask.addOnCompleteListener {
-                // We must call image.close() on received images when finished using them.
-                // Otherwise, new images may not be received or the camera may stall.
-                imageProxy.close()
-            }
-            barcodeTask.addOnSuccessListener { barcodeList ->
-                // The check for barcodeFound is done because the startScan method will be called
-                // continuously by the library as long as we are in the scanning screen.
-                // There will be a good chance that the same barcode gets identified multiple times and as a result
-                // success callback will be called multiple times.
-                if (!barcodeList.isNullOrEmpty() && !barcodeFound) {
-                    barcodeFound = true
-                    handleScanSuccess(barcodeList.firstOrNull())
-                    this@callbackFlow.close()
-                }
-            }
-            barcodeTask.addOnFailureListener { exception ->
-                this@callbackFlow.trySend(
-                    CodeScannerStatus.Failure(
-                        error = exception.message,
-                        type = errorMapper.mapGoogleMLKitScanningErrors(exception)
-                    )
-                )
-                this@callbackFlow.close()
-            }
-
-            awaitClose()
-        }
-    }
-
-    private fun ProducerScope<CodeScannerStatus>.handleScanSuccess(code: Barcode?) {
-        code?.rawValue?.let {
-            trySend(
-                CodeScannerStatus.Success(
-                    it,
-                    barcodeFormatMapper.mapBarcodeFormat(code.format)
-                )
-            )
-        } ?: run {
-            trySend(
-                CodeScannerStatus.Failure(
-                    error = "Failed to find a valid raw value!",
-                    type = CodeScanningErrorType.Other(Throwable("Empty raw value"))
-                )
-            )
-        }
-    }
-}
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/InputImageProvider.kt b/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/InputImageProvider.kt
deleted file mode 100644
index 2184e4bcbe7e..000000000000
--- a/WordPress/src/main/java/org/wordpress/android/ui/barcodescanner/InputImageProvider.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.wordpress.android.ui.barcodescanner
-
-import androidx.camera.core.ImageProxy
-import com.google.mlkit.vision.common.InputImage
-import javax.inject.Inject
-
-interface InputImageProvider {
-    fun provideImage(imageProxy: ImageProxy): InputImage
-}
-class MediaImageProvider @Inject constructor() : InputImageProvider {
-    @androidx.camera.core.ExperimentalGetImage
-    override fun provideImage(imageProxy: ImageProxy): InputImage {
-        return InputImage.fromMediaImage(imageProxy.image!!, imageProxy.imageInfo.rotationDegrees)
-    }
-}
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/qrcodeauth/QRCodeAuthFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/qrcodeauth/QRCodeAuthFragment.kt
index 90701d21939d..d006711d1277 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/qrcodeauth/QRCodeAuthFragment.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/qrcodeauth/QRCodeAuthFragment.kt
@@ -13,21 +13,15 @@ import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.ComposeView
 import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentResultListener
-import androidx.fragment.app.FragmentTransaction
 import androidx.fragment.app.activityViewModels
 import androidx.fragment.app.viewModels
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.viewmodel.compose.viewModel
+import com.google.mlkit.vision.codescanner.GmsBarcodeScanning
 import dagger.hilt.android.AndroidEntryPoint
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
-import org.wordpress.android.R
 import org.wordpress.android.analytics.AnalyticsTracker.Stat
-import org.wordpress.android.ui.barcodescanner.BarcodeScanningFragment
-import org.wordpress.android.ui.barcodescanner.BarcodeScanningFragment.Companion.KEY_BARCODE_SCANNING_REQUEST
-import org.wordpress.android.ui.barcodescanner.BarcodeScanningFragment.Companion.KEY_BARCODE_SCANNING_SCAN_STATUS
-import org.wordpress.android.ui.barcodescanner.CodeScannerStatus
 import org.wordpress.android.ui.compose.components.VerticalScrollBox
 import org.wordpress.android.ui.compose.theme.AppTheme
 import org.wordpress.android.ui.posts.BasicDialogViewModel
@@ -52,18 +46,9 @@ import javax.inject.Inject
 class QRCodeAuthFragment : Fragment() {
     @Inject
     lateinit var uiHelpers: UiHelpers
-
     private val qrCodeAuthViewModel: QRCodeAuthViewModel by viewModels()
     private val dialogViewModel: BasicDialogViewModel by activityViewModels()
 
-    @Suppress("DEPRECATION")
-    private val resultListener = FragmentResultListener { requestKey, result ->
-        if (requestKey == KEY_BARCODE_SCANNING_REQUEST) {
-            val resultValue = result.getParcelable<CodeScannerStatus?>(KEY_BARCODE_SCANNING_SCAN_STATUS)
-            resultValue?.let { qrCodeAuthViewModel.handleScanningResult(it) }
-        }
-    }
-
     override fun onCreateView(
         inflater: LayoutInflater,
         container: ViewGroup?,
@@ -75,12 +60,10 @@ class QRCodeAuthFragment : Fragment() {
             }
         }
     }
-
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
         initBackPressHandler()
         initViewModel(savedInstanceState)
-        initScannerResultListener()
         observeViewModel()
     }
 
@@ -88,25 +71,15 @@ class QRCodeAuthFragment : Fragment() {
         qrCodeAuthViewModel.actionEvents.onEach(this::handleActionEvents).launchIn(viewLifecycleOwner.lifecycleScope)
         dialogViewModel.onInteraction.observeEvent(viewLifecycleOwner, qrCodeAuthViewModel::onDialogInteraction)
     }
-
     private fun initViewModel(savedInstanceState: Bundle?) {
         val (uri, isDeepLink) = requireActivity().intent?.extras?.let {
             val uri = it.getString(DEEP_LINK_URI_KEY, null)
             val isDeepLink = it.getBoolean(IS_DEEP_LINK_KEY, false)
             uri to isDeepLink
         } ?: (null to false)
-
         qrCodeAuthViewModel.start(uri, isDeepLink, savedInstanceState)
     }
 
-    private fun initScannerResultListener() {
-        requireActivity().supportFragmentManager.setFragmentResultListener(
-            KEY_BARCODE_SCANNING_REQUEST,
-            viewLifecycleOwner,
-            resultListener
-        )
-    }
-
     private fun handleActionEvents(actionEvent: QRCodeAuthActionEvent) {
         when (actionEvent) {
             is LaunchDismissDialog -> launchDismissDialog(actionEvent.dialogModel)
@@ -114,7 +87,6 @@ class QRCodeAuthFragment : Fragment() {
             is FinishActivity -> requireActivity().finish()
         }
     }
-
     private fun launchDismissDialog(model: QRCodeAuthDialogModel) {
         dialogViewModel.showDialog(
             requireActivity().supportFragmentManager,
@@ -124,22 +96,17 @@ class QRCodeAuthFragment : Fragment() {
                 getString(model.message),
                 getString(model.positiveButtonLabel),
                 model.negativeButtonLabel?.let { label -> getString(label) },
-                model.cancelButtonLabel?.let { label -> getString(label) },
-                false
+                model.cancelButtonLabel?.let { label -> getString(label) }
             )
         )
     }
 
     private fun launchScanner() {
         qrCodeAuthViewModel.track(Stat.QRLOGIN_SCANNER_DISPLAYED)
-        replaceFragment(BarcodeScanningFragment())
-    }
-
-    private fun replaceFragment(fragment: Fragment) {
-        val transaction: FragmentTransaction = requireActivity().supportFragmentManager.beginTransaction()
-        transaction.replace(R.id.fragment_container, fragment)
-        transaction.addToBackStack(null)
-        transaction.commit()
+        val scanner = GmsBarcodeScanning.getClient(requireContext())
+        scanner.startScan()
+            .addOnSuccessListener { barcode -> qrCodeAuthViewModel.onScanSuccess(barcode.rawValue) }
+            .addOnFailureListener { qrCodeAuthViewModel.onScanFailure() }
     }
 
     private fun initBackPressHandler() {
@@ -147,13 +114,11 @@ class QRCodeAuthFragment : Fragment() {
             qrCodeAuthViewModel.onBackPressed()
         }
     }
-
     override fun onSaveInstanceState(outState: Bundle) {
         qrCodeAuthViewModel.writeToBundle(outState)
         super.onSaveInstanceState(outState)
     }
 }
-
 @Composable
 private fun QRCodeAuthScreen(viewModel: QRCodeAuthViewModel = viewModel()) {
     VerticalScrollBox(
@@ -161,7 +126,6 @@ private fun QRCodeAuthScreen(viewModel: QRCodeAuthViewModel = viewModel()) {
         modifier = Modifier.fillMaxSize()
     ) {
         val uiState by viewModel.uiState.collectAsState()
-
         @Suppress("UnnecessaryVariable") // See: https://stackoverflow.com/a/69558316/4129245
         when (val state = uiState) {
             is Content -> ContentState(state)
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/qrcodeauth/QRCodeAuthViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/qrcodeauth/QRCodeAuthViewModel.kt
index 8fba57d11a90..c17c5f267e16 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/qrcodeauth/QRCodeAuthViewModel.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/qrcodeauth/QRCodeAuthViewModel.kt
@@ -23,9 +23,6 @@ import org.wordpress.android.fluxc.network.rest.wpcom.qrcodeauth.QRCodeAuthError
 import org.wordpress.android.fluxc.store.qrcodeauth.QRCodeAuthStore
 import org.wordpress.android.fluxc.store.qrcodeauth.QRCodeAuthStore.QRCodeAuthResult
 import org.wordpress.android.fluxc.store.qrcodeauth.QRCodeAuthStore.QRCodeAuthValidateResult
-import org.wordpress.android.ui.barcodescanner.BarcodeScanningTracker
-import org.wordpress.android.ui.barcodescanner.CodeScannerStatus
-import org.wordpress.android.ui.barcodescanner.ScanningSource
 import org.wordpress.android.ui.posts.BasicDialogViewModel.DialogInteraction
 import org.wordpress.android.ui.posts.BasicDialogViewModel.DialogInteraction.Dismissed
 import org.wordpress.android.ui.posts.BasicDialogViewModel.DialogInteraction.Negative
@@ -55,15 +52,12 @@ class QRCodeAuthViewModel @Inject constructor(
     private val uiStateMapper: QRCodeAuthUiStateMapper,
     private val networkUtilsWrapper: NetworkUtilsWrapper,
     private val validator: QRCodeAuthValidator,
-    private val analyticsTrackerWrapper: AnalyticsTrackerWrapper,
-    private val barcodeScanningTracker: BarcodeScanningTracker
+    private val analyticsTrackerWrapper: AnalyticsTrackerWrapper
 ) : ViewModel() {
     private val _actionEvents = Channel<QRCodeAuthActionEvent>(Channel.BUFFERED)
     val actionEvents = _actionEvents.receiveAsFlow()
-
     private val _uiState = MutableStateFlow<QRCodeAuthUiState>(Loading)
     val uiState: StateFlow<QRCodeAuthUiState> = _uiState
-
     private var trackingOrigin: String? = null
     private var data: String? = null
     private var token: String? = null
@@ -71,13 +65,10 @@ class QRCodeAuthViewModel @Inject constructor(
     private var browser: String? = null
     private var lastState: QRCodeAuthUiStateType? = null
     private var isStarted = false
-
     fun start(uri: String? = null, isDeepLink: Boolean = false, savedInstanceState: Bundle? = null) {
         if (isStarted) return
         isStarted = true
-
         extractSavedInstanceStateIfNeeded(savedInstanceState)
-
         if (isDeepLink && savedInstanceState == null) {
             trackingOrigin = ORIGIN_DEEPLINK
             process(uri)
@@ -95,7 +86,7 @@ class QRCodeAuthViewModel @Inject constructor(
             location = savedInstanceState.getString(LOCATION_KEY, null)
             trackingOrigin = savedInstanceState.getString(TRACKING_ORIGIN_KEY, ORIGIN_MENU)
             lastState = QRCodeAuthUiStateType.fromString(savedInstanceState.getString(LAST_STATE_KEY, null))
-         }
+        }
     }
 
     private fun startOrRestoreUiState() {
@@ -109,6 +100,7 @@ class QRCodeAuthViewModel @Inject constructor(
                     this::onAuthenticateCancelClicked
                 )
             )
+
             AUTHENTICATING -> postUiState(uiStateMapper.mapToAuthenticating(location = location, browser = browser))
             DONE -> postUiState(uiStateMapper.mapToDone(this::onDismissClicked))
             // errors
@@ -119,37 +111,25 @@ class QRCodeAuthViewModel @Inject constructor(
                     this::onCancelClicked
                 )
             )
+
             EXPIRED_TOKEN -> postUiState(uiStateMapper.mapToExpired(this::onScanAgainClicked, this::onCancelClicked))
             NO_INTERNET -> {
                 postUiState(uiStateMapper.mapToNoInternet(this::onScanAgainClicked, this::onCancelClicked))
             }
-            else -> updateUiStateAndLaunchScanner()
-        }
-    }
 
-    fun handleScanningResult(status: CodeScannerStatus) {
-        when (status) {
-            is CodeScannerStatus.Success -> onScanSuccess(status.code)
-            is CodeScannerStatus.Failure -> onScanFailure(status)
-            is CodeScannerStatus.Exit -> onExit()
-            is CodeScannerStatus.NavigateUp -> onBackPressed()
+            else -> updateUiStateAndLaunchScanner()
         }
     }
 
     //  https://apps.wordpress.com/get/?campaign=login-qr-code#qr-code-login?token=asdfadsfa&data=asdfasdf
     fun onScanSuccess(scannedValue: String?) {
-        barcodeScanningTracker.trackSuccess(ScanningSource.QRCODE_LOGIN)
         track(Stat.QRLOGIN_SCANNER_SCANNED_CODE)
         process(scannedValue)
     }
 
-    fun onScanFailure(status: CodeScannerStatus.Failure) {
-        barcodeScanningTracker.trackScanFailure(ScanningSource.QRCODE_LOGIN, status.type)
-        postActionEvent(FinishActivity)
-    }
-
-    private fun onExit() {
-        track(Stat.QRLOGIN_SCANNER_DISMISSED_CAMERA_PERMISSION_DENIED)
+    fun onScanFailure() {
+        // Note: This is a result of the tap on "X" within the scanner view
+        track(Stat.QRLOGIN_SCANNER_DISMISSED)
         postActionEvent(FinishActivity)
     }
 
@@ -191,9 +171,7 @@ class QRCodeAuthViewModel @Inject constructor(
     private fun process(input: String?) {
         clearProperties()
         extractQueryParamsIfValid(input)
-
         track(Stat.QRLOGIN_VERIFY_DISPLAYED)
-
         if (data.isNullOrEmpty() || token.isNullOrEmpty()) {
             track(QRLOGIN_VERIFY_FAILED, TRACK_INVALID_DATA)
             postUiState(uiStateMapper.mapToInvalidData(this::onScanAgainClicked, this::onCancelClicked))
@@ -209,7 +187,6 @@ class QRCodeAuthViewModel @Inject constructor(
             postUiState(uiStateMapper.mapToNoInternet(this::onScanAgainClicked, this::onCancelClicked))
             return
         }
-
         viewModelScope.launch {
             val result = authStore.validate(data = data, token = token)
             if (result.isError) {
@@ -242,6 +219,7 @@ class QRCodeAuthViewModel @Inject constructor(
                 uiStateMapper.mapToAuthFailed(this::onScanAgainClicked, this::onCancelClicked)
             }
         }
+
         GENERIC_ERROR,
         INVALID_RESPONSE,
         REST_INVALID_PARAM,
@@ -252,7 +230,6 @@ class QRCodeAuthViewModel @Inject constructor(
 
     private fun extractQueryParamsIfValid(scannedValue: String?) {
         if (!validator.isValidUri(scannedValue)) return
-
         val queryParams = validator.extractQueryParams(scannedValue)
         if (queryParams.containsKey(DATA_KEY) && queryParams.containsKey(TOKEN_KEY)) {
             this.data = queryParams[DATA_KEY].toString()
@@ -266,7 +243,6 @@ class QRCodeAuthViewModel @Inject constructor(
             postUiState(uiStateMapper.mapToNoInternet(this::onScanAgainClicked, this::onCancelClicked))
             return
         }
-
         viewModelScope.launch {
             val result = authStore.authenticate(data = data, token = token)
             if (result.isError) {
@@ -287,7 +263,6 @@ class QRCodeAuthViewModel @Inject constructor(
     }
 
     private fun mapAuthenticateSuccessToDoneState() = uiStateMapper.mapToDone(this::onDismissClicked)
-
     private fun updateUiStateAndLaunchScanner() {
         postUiState(uiStateMapper.mapToScanning())
         postActionEvent(LaunchScanner)
@@ -307,11 +282,8 @@ class QRCodeAuthViewModel @Inject constructor(
 
     fun onDialogInteraction(interaction: DialogInteraction) {
         when (interaction) {
-            is Positive -> {
-                track(Stat.QRLOGIN_SCANNER_DISMISSED)
-                postActionEvent(FinishActivity)
-            }
-            is Negative -> onScanAgainClicked()
+            is Positive -> postActionEvent(FinishActivity)
+            is Negative -> Unit
             is Dismissed -> Unit
         }
     }
diff --git a/WordPress/src/main/res/values/strings.xml b/WordPress/src/main/res/values/strings.xml
index da38d8cbe288..54c120aa1e18 100644
--- a/WordPress/src/main/res/values/strings.xml
+++ b/WordPress/src/main/res/values/strings.xml
@@ -4803,14 +4803,14 @@ translators: %s: Select control option value e.g: "Auto, 25%". -->
     <!--
          Barcode Scanning
     -->
-    <string name="barcode_scanning_title">Scan Barcode</string>
-    <string name="barcode_scanning_camera_permission_denied">Camera permission is required to scan the barcode.</string>
-    <string name="barcode_scanning_alert_dialog_title">Grant Camera Permission</string>
-    <string name="barcode_scanning_alert_dialog_rationale_message">Camera permission is required in order to scan the barcode</string>
-    <string name="barcode_scanning_alert_dialog_permanently_denied_message">You have permanently denied Camera permission. It is required in order to scan the barcode. Please enable it from the app settings</string>
-    <string name="barcode_scanning_alert_dialog_rationale_cta_label">Grant</string>
-    <string name="barcode_scanning_alert_dialog_dismiss_label">Cancel</string>
-    <string name="barcode_scanning_alert_dialog_permanently_denied_cta_label">Go to settings</string>
+    <string name="barcode_scanning_title" tools:ignore="UnusedResources">Scan Barcode</string>
+    <string name="barcode_scanning_camera_permission_denied" tools:ignore="UnusedResources">Camera permission is required to scan the barcode.</string>
+    <string name="barcode_scanning_alert_dialog_title" tools:ignore="UnusedResources">Grant Camera Permission</string>
+    <string name="barcode_scanning_alert_dialog_rationale_message" tools:ignore="UnusedResources">Camera permission is required in order to scan the barcode</string>
+    <string name="barcode_scanning_alert_dialog_permanently_denied_message" tools:ignore="UnusedResources">You have permanently denied Camera permission. It is required in order to scan the barcode. Please enable it from the app settings</string>
+    <string name="barcode_scanning_alert_dialog_rationale_cta_label" tools:ignore="UnusedResources">Grant</string>
+    <string name="barcode_scanning_alert_dialog_dismiss_label" tools:ignore="UnusedResources">Cancel</string>
+    <string name="barcode_scanning_alert_dialog_permanently_denied_cta_label" tools:ignore="UnusedResources">Go to settings</string>
 
     <string name="login_text_security_key" tools:ignore="UnusedResources" a8c-src-lib="login">Use a security key</string>
     <string name="login_error_security_key" tools:ignore="UnusedResources" a8c-src-lib="login">There was some trouble with the Security key login</string>
diff --git a/build.gradle b/build.gradle
index 020e83bbd311..2a1184ec5610 100644
--- a/build.gradle
+++ b/build.gradle
@@ -37,7 +37,6 @@ ext {
     androidxAnnotationVersion = '1.6.0'
     androidxAppcompatVersion = '1.6.1'
     androidxArchCoreVersion = '2.2.0'
-    androidxCameraVersion = '1.2.3'
     androidxComposeBomVersion = '2023.10.00'
     androidxComposeCompilerVersion = '1.5.3'
     androidxCardviewVersion = '1.0.0'
@@ -70,8 +69,6 @@ ext {
     googleGsonVersion = '2.10.1'
     googleMaterialVersion = '1.9.0'
 
-    mlkitBarcodeScanningVersion = '17.2.0'
-    mlkitTextRecognitionVersion = '16.0.0'
     googleMLKitBarcodeScanningVersion = '17.0.0'
     googlePlayServicesAuthVersion = '20.4.1'
     googlePlayServicesCodeScannerVersion = '16.0.0-beta3'


Test patch:
diff --git a/WordPress/src/test/java/org/wordpress/android/ui/qrcodeauth/QRCodeAuthViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/qrcodeauth/QRCodeAuthViewModelTest.kt
index 6088a7c684c3..7ef417a884f2 100644
--- a/WordPress/src/test/java/org/wordpress/android/ui/qrcodeauth/QRCodeAuthViewModelTest.kt
+++ b/WordPress/src/test/java/org/wordpress/android/ui/qrcodeauth/QRCodeAuthViewModelTest.kt
@@ -28,10 +28,6 @@ import org.wordpress.android.fluxc.store.qrcodeauth.QRCodeAuthStore
 import org.wordpress.android.fluxc.store.qrcodeauth.QRCodeAuthStore.QRCodeAuthAuthenticateResult
 import org.wordpress.android.fluxc.store.qrcodeauth.QRCodeAuthStore.QRCodeAuthResult
 import org.wordpress.android.fluxc.store.qrcodeauth.QRCodeAuthStore.QRCodeAuthValidateResult
-import org.wordpress.android.ui.barcodescanner.BarcodeScanningTracker
-import org.wordpress.android.ui.barcodescanner.CodeScannerStatus
-import org.wordpress.android.ui.barcodescanner.CodeScanningErrorType
-import org.wordpress.android.ui.barcodescanner.ScanningSource
 import org.wordpress.android.ui.posts.BasicDialogViewModel.DialogInteraction
 import org.wordpress.android.ui.qrcodeauth.QRCodeAuthUiState.Content.Done
 import org.wordpress.android.ui.qrcodeauth.QRCodeAuthUiState.Content.Validated
@@ -84,8 +80,6 @@ class QRCodeAuthViewModelTest : BaseUnitTest() {
     @Mock
     lateinit var analyticsTrackerWrapper: AnalyticsTrackerWrapper
 
-    @Mock
-    lateinit var barcodeScanningTracker: BarcodeScanningTracker
     private val uiStateMapper = QRCodeAuthUiStateMapper()
 
     private val validQueryParams = mapOf(DATA_KEY to DATA, TOKEN_KEY to TOKEN)
@@ -95,8 +89,6 @@ class QRCodeAuthViewModelTest : BaseUnitTest() {
     private val errorTrackingMapAuthFailed = mutableMapOf("error" to "authentication_failed", "origin" to "menu")
     private val errorTrackingMapExpiredToken = mutableMapOf("error" to "expired_token", "origin" to "menu")
 
-    private val failureStatus = CodeScannerStatus.Failure("Failure", CodeScanningErrorType.Unknown)
-
     @Before
     fun setUp() {
         viewModel = QRCodeAuthViewModel(
@@ -104,8 +96,7 @@ class QRCodeAuthViewModelTest : BaseUnitTest() {
             uiStateMapper,
             networkUtilsWrapper,
             validator,
-            analyticsTrackerWrapper,
-            barcodeScanningTracker
+            analyticsTrackerWrapper
         )
 
         whenever(networkUtilsWrapper.isNetworkAvailable()).thenReturn(true)
@@ -207,7 +198,6 @@ class QRCodeAuthViewModelTest : BaseUnitTest() {
             viewModel.start()
             viewModel.onScanSuccess(SCANNED_VALUE)
 
-            verify(barcodeScanningTracker).trackSuccess(ScanningSource.QRCODE_LOGIN)
             verify(analyticsTrackerWrapper).track(eq(QRLOGIN_VERIFY_FAILED), eq(errorTrackingMapInvalidData))
         }
     }
@@ -520,22 +510,12 @@ class QRCodeAuthViewModelTest : BaseUnitTest() {
     fun `when scan fails, then finish activity event is raised`() {
         val actionEvents = mutableListOf<QRCodeAuthActionEvent>()
         testWithData(actionEvents = actionEvents) {
-            viewModel.onScanFailure(failureStatus)
+            viewModel.onScanFailure()
 
             assertThat(actionEvents.last()).isInstanceOf(QRCodeAuthActionEvent.FinishActivity::class.java)
         }
     }
 
-    @Test
-    fun `when scan fails, then scan failed is tracked`() {
-        val actionEvents = mutableListOf<QRCodeAuthActionEvent>()
-        testWithData(actionEvents = actionEvents) {
-            viewModel.onScanFailure(failureStatus)
-
-            verify(barcodeScanningTracker).trackScanFailure(ScanningSource.QRCODE_LOGIN, failureStatus.type)
-        }
-    }
-
     @Test
     fun `given valid scan, when no network connection, then no internet error is shown`() {
         val uiStates = mutableListOf<QRCodeAuthUiState>()