Repository: flutter
Issue: [camera_android_camerax] add error info to onCameraError when camera fails to open. 
Labels: e: device-specific,platform-android,p: camera,package,e: OS-version specific,P2,team-android,triaged-android

## Add camera failing to open as a class of error reported to onCameraError 
Sometimes android cameras have physical hardware errors that prevent opening. Expose failure to open camera as an error in onCameraError so that developers in camera_android_camerax can respond to this condition for their users. 

https://github.com/flutter/flutter/issues/153091#issuecomment-2297000695


## Original report below
### Steps to reproduce

1. Create a flutter app with the minimal setup below
2. After giving permissions, click on the "capture image" button
3. the console will log 'Taking picture...' but will not log 'Picture taken: ${file.path}' or any errors other than the below in "actual results"

### Expected results

taking a photo should work as expected

### Actual results

Nothing happens. No picture was taken, 'Picture taken: ${file.path}' is never printed,  I get the error logs below. When I click on the button a 2nd time I get:
```console
I/flutter (25579): Already taking a picture.
```

### Code sample

<details open><summary>Code sample</summary>

```dart
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';

List<CameraDescription> cameras = [];
CameraController? controller;

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  cameras = await availableCameras();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: CameraApp());
  }
}

class CameraApp extends StatefulWidget {
  const CameraApp({super.key});

  @override
  CameraAppState createState() => CameraAppState();
}

class CameraAppState extends State<CameraApp> {
  @override
  void initState() {
    super.initState();
    checkCameraPermissions();
  }

  void checkCameraPermissions() async {
    final status = await Permission.camera.status;
    if (!status.isGranted) {
      await Permission.camera.request();
    }
    if (await Permission.camera.isGranted) {
      onNewCameraSelected(cameras.first);
    } else {
      print('Camera permission not granted');
    }
  }

  void _showCameraException(CameraException e) {
    print('Error: ${e.code}\nError Message: ${e.description}');
  }

  Future<void> captureImage() async {
    if (controller == null) {
      print('Camera controller is null.');
      return;
    }

    if (!controller!.value.isInitialized) {
      print('Camera is not initialized.');
      return;
    }

    if (controller!.value.isTakingPicture) {
      print('Already taking a picture.');
      return;
    }

    print('Taking picture...');
    try {
      final XFile file = await controller!.takePicture();
      print('Picture taken: ${file.path}');
    } on CameraException catch (e) {
      _showCameraException(e);
    } catch (e) {
      print('Unexpected error: $e');
    }
  }

  void onNewCameraSelected(CameraDescription cameraDescription) async {
    print('Selecting new camera: ${cameraDescription.name}');
    final previousCameraController = controller;
    if (previousCameraController != null) {
      await previousCameraController.dispose();
    }

    final CameraController cameraController = CameraController(
      cameraDescription,
      ResolutionPreset.medium,
      enableAudio: false,
    );

    setState(() {
      controller = cameraController;
    });

    cameraController.addListener(() {
      if (mounted) setState(() {});
      if (cameraController.value.hasError) {
        print('Camera error: ${cameraController.value.errorDescription}');
      }
    });

    try {
      await cameraController.initialize();
      print('Camera initialized');
    } on CameraException catch (e) {
      _showCameraException(e);
    }

    if (mounted) setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Camera Example')),
      body: Column(
        children: <Widget>[
          if (controller != null && controller!.value.isInitialized)
            CameraPreview(controller!)
          else
            const Text('Camera not initialized'),
          ElevatedButton(
            onPressed: captureImage,
            child: const Text('Capture Image'),
          ),
        ],
      ),
    );
  }
}
```

Additionally:
```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app" xmlns:tools="http://schemas.android.com/tools">

  <uses-feature
      android:name="android.hardware.camera"
      android:required="false" />
  <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.CAMERA"/>
  <uses-permission android:name="android.permission.RECORD_AUDIO"/>
```

</details>


### Screenshots or Video

<details open>
<summary>Screenshots / Video demonstration</summary>

[Upload media here]

</details>


### Logs

<details open><summary>Logs</summary>

```console
I/flutter (25579): Taking picture...
D/ImageCapture(25579): takePictureInternal
D/CameraOrientationUtil(25579): getRelativeImageRotation: destRotationDegrees=0, sourceRotationDegrees=90, isOppositeFacing=true, result=90
D/TakePictureManager(25579): Issue the next TakePictureRequest.
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Issue capture request
D/CaptureSession(25579): Issuing capture request.
D/Camera2CaptureRequestBuilder(25579): createCaptureRequest
D/DeferrableSurface(25579): use count-1,  useCount=1 closed=false androidx.camera.core.SurfaceRequest$2@f56169d
D/DeferrableSurface(25579): use count-1,  useCount=0 closed=false androidx.camera.core.impl.ImmediateSurface@476763f
D/DeferrableSurface(25579): Surface no longer in use[total_surfaces=4, used_surfaces=2](androidx.camera.core.impl.ImmediateSurface@476763f}
D/DeferrableSurface(25579): use count-1,  useCount=0 closed=false androidx.camera.core.impl.ImmediateSurface@d727c55
D/DeferrableSurface(25579): Surface no longer in use[total_surfaces=4, used_surfaces=1](androidx.camera.core.impl.ImmediateSurface@d727c55}
D/Camera2CameraImpl(25579): CameraDevice.onError(): 0 failed with ERROR_CAMERA_DEVICE while in OPENED state. Will attempt recovering from error.
D/Camera2CameraImpl(25579): Attempt to reopen camera[0] after error[ERROR_CAMERA_DEVICE]
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Transitioning camera internal state: OPENED --> REOPENING
D/CameraStateRegistry(25579): Recalculating open cameras:
D/CameraStateRegistry(25579): Camera                                       State                 
D/CameraStateRegistry(25579): -------------------------------------------------------------------
D/CameraStateRegistry(25579): Camera@2c97479[id=0]                         OPENING               
D/CameraStateRegistry(25579): Camera@1a2853b[id=1]                         UNKNOWN               
D/CameraStateRegistry(25579): -------------------------------------------------------------------
D/CameraStateRegistry(25579): Open count: 1 (Max allowed: 1)
D/CameraStateMachine(25579): New public camera state CameraState{type=OPENING, error=StateError{code=3, cause=null}} from OPENING and StateError{code=3, cause=null}
D/CameraStateMachine(25579): Publishing new public camera state CameraState{type=OPENING, error=StateError{code=3, cause=null}}
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Resetting Capture Session
E/ObserverFlutterApi(25579): The Observer that received a callback has been garbage collected. Please create a new instance to receive any further data changes.
E/ObserverFlutterApi(25579): The Observer that received a callback has been garbage collected. Please create a new instance to receive any further data changes.
E/CameraCaptureSession(25579): Session 0: Exception while stopping repeating: 
E/CameraCaptureSession(25579): android.hardware.camera2.CameraAccessException: CAMERA_ERROR (3): The camera device has encountered a serious error
E/CameraCaptureSession(25579): 	at android.hardware.camera2.impl.CameraDeviceImpl.checkIfCameraClosedOrInError(CameraDeviceImpl.java:2521)
E/CameraCaptureSession(25579): 	at android.hardware.camera2.impl.CameraDeviceImpl.stopRepeating(CameraDeviceImpl.java:1128)
E/CameraCaptureSession(25579): 	at android.hardware.camera2.impl.CameraCaptureSessionImpl.close(CameraCaptureSessionImpl.java:526)
E/CameraCaptureSession(25579): 	at androidx.camera.camera2.internal.SynchronizedCaptureSessionBaseImpl.close(SynchronizedCaptureSessionBaseImpl.java:476)
E/CameraCaptureSession(25579): 	at androidx.camera.camera2.internal.CaptureSession.release(CaptureSession.java:526)
E/CameraCaptureSession(25579): 	at androidx.camera.camera2.internal.Camera2CameraImpl.releaseSession(Camera2CameraImpl.java:555)
E/CameraCaptureSession(25579): 	at androidx.camera.camera2.internal.Camera2CameraImpl.resetCaptureSession(Camera2CameraImpl.java:1329)
E/CameraCaptureSession(25579): 	at androidx.camera.camera2.internal.Camera2CameraImpl.closeCamera(Camera2CameraImpl.java:468)
E/CameraCaptureSession(25579): 	at androidx.camera.camera2.internal.Camera2CameraImpl$StateCallback.reopenCameraAfterError(Camera2CameraImpl.java:1827)
E/CameraCaptureSession(25579): 	at androidx.camera.camera2.internal.Camera2CameraImpl$StateCallback.handleErrorOnOpen(Camera2CameraImpl.java:1779)
E/CameraCaptureSession(25579): 	at androidx.camera.camera2.internal.Camera2CameraImpl$StateCallback.onError(Camera2CameraImpl.java:1754)
E/CameraCaptureSession(25579): 	at androidx.camera.camera2.internal.CameraDeviceStateCallbacks$ComboDeviceStateCallback.onError(CameraDeviceStateCallbacks.java:121)
E/CameraCaptureSession(25579): 	at android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks.notifyError(CameraDeviceImpl.java:2010)
E/CameraCaptureSession(25579): 	at android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks.lambda$Sm85frAzwGZVMAK-NE_gwckYXVQ(Unknown Source:0)
E/CameraCaptureSession(25579): 	at android.hardware.camera2.impl.-$$Lambda$CameraDeviceImpl$CameraDeviceCallbacks$Sm85frAzwGZVMAK-NE_gwckYXVQ.accept(Unknown Source:8)
E/CameraCaptureSession(25579): 	at com.android.internal.util.function.pooled.PooledLambdaImpl.doInvoke(PooledLambdaImpl.java:271)
E/CameraCaptureSession(25579): 	at com.android.internal.util.function.pooled.PooledLambdaImpl.invoke(PooledLambdaImpl.java:195)
E/CameraCaptureSession(25579): 	at com.android.internal.util.function.pooled.OmniFunction.run(OmniFunction.java:86)
E/CameraCaptureSession(25579): 	at androidx.camera.core.impl.utils.executor.SequentialExecutor$1.run(SequentialExecutor.java:111)
E/CameraCaptureSession(25579): 	at androidx.camera.core.impl.utils.executor.SequentialExecutor$QueueWorker.workOnQueue(SequentialExecutor.java:231)
E/CameraCaptureSession(25579): 	at androidx.camera.core.impl.utils.executor.SequentialExecutor$QueueWorker.run(SequentialExecutor.java:173)
E/CameraCaptureSession(25579): 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/CameraCaptureSession(25579): 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/CameraCaptureSession(25579): 	at java.lang.Thread.run(Thread.java:919)
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Releasing session in state REOPENING
D/CaptureSession(25579): onSessionFinished()
D/HostConnection(25579): HostConnection::get() New Host Connection established 0x6f8b7e1980, tid 25923
D/HostConnection(25579): HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_vulkan ANDROID_EMU_deferred_vulkan_commands ANDROID_EMU_vulkan_null_optional_strings ANDROID_EMU_vulkan_create_resources_with_requirements ANDROID_EMU_YUV_Cache ANDROID_EMU_vulkan_ignored_handles ANDROID_EMU_vulkan_free_memory_sync ANDROID_EMU_vulkan_shader_float16_int8 ANDROID_EMU_vulkan_async_queue_submit ANDROID_EMU_sync_buffer_data ANDROID_EMU_vulkan_async_qsri GL_OES_EGL_image_external_essl3 GL_OES_vertex_array_object ANDROID_EMU_host_side_tracing ANDROID_EMU_gles_max_version_3_0 
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} CameraDevice.onClosed()
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Camera closed due to error: ERROR_CAMERA_DEVICE
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Attempting camera re-open in 700ms: androidx.camera.camera2.internal.Camera2CameraImpl$StateCallback$ScheduledReopen@38ded59 activeResuming = true
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Attempting to open the camera.
D/CameraStateRegistry(25579): tryOpenCamera(Camera@2c97479[id=0]) [Available Cameras: 0, Already Open: true (Previous state: OPENING)] --> SUCCESS
D/CameraStateRegistry(25579): Recalculating open cameras:
D/CameraStateRegistry(25579): Camera                                       State                 
D/CameraStateRegistry(25579): -------------------------------------------------------------------
D/CameraStateRegistry(25579): Camera@2c97479[id=0]                         OPENING               
D/CameraStateRegistry(25579): Camera@1a2853b[id=1]                         UNKNOWN               
D/CameraStateRegistry(25579): -------------------------------------------------------------------
D/CameraStateRegistry(25579): Open count: 1 (Max allowed: 1)
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Cancelling scheduled re-open: androidx.camera.camera2.internal.Camera2CameraImpl$StateCallback$ScheduledReopen@38ded59
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Opening camera.
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Transitioning camera internal state: REOPENING --> OPENING
D/CameraStateMachine(25579): New public camera state CameraState{type=OPENING, error=null} from OPENING and null
D/CameraStateMachine(25579): Publishing new public camera state CameraState{type=OPENING, error=null}
E/ObserverFlutterApi(25579): The Observer that received a callback has been garbage collected. Please create a new instance to receive any further data changes.
E/ObserverFlutterApi(25579): The Observer that received a callback has been garbage collected. Please create a new instance to receive any further data changes.
D/UseCaseAttachState(25579): All use case: [androidx.camera.core.ImageCapture-cf6e2bfe-40b0-4baa-bd0c-e81950c3efff67248482, androidx.camera.core.Preview-91464e5c-8831-4aa5-b269-f8ad4b4b0b7c248335614, androidx.camera.core.ImageAnalysis-03c9c5f5-ee0b-4640-8564-af627c4166c681050544] for camera: 0
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} CameraDevice.onOpened()
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Transitioning camera internal state: OPENING --> OPENED
D/CameraStateRegistry(25579): Recalculating open cameras:
D/CameraStateRegistry(25579): Camera                                       State                 
D/CameraStateRegistry(25579): -------------------------------------------------------------------
D/CameraStateRegistry(25579): Camera@2c97479[id=0]                         OPEN                  
D/CameraStateRegistry(25579): Camera@1a2853b[id=1]                         UNKNOWN               
D/CameraStateRegistry(25579): -------------------------------------------------------------------
D/CameraStateRegistry(25579): Open count: 1 (Max allowed: 1)
D/CameraStateMachine(25579): New public camera state CameraState{type=OPEN, error=null} from OPEN and null
D/CameraStateMachine(25579): Publishing new public camera state CameraState{type=OPEN, error=null}
E/ObserverFlutterApi(25579): The Observer that received a callback has been garbage collected. Please create a new instance to receive any further data changes.
E/ObserverFlutterApi(25579): The Observer that received a callback has been garbage collected. Please create a new instance to receive any further data changes.
D/UseCaseAttachState(25579): All use case: [androidx.camera.core.ImageCapture-cf6e2bfe-40b0-4baa-bd0c-e81950c3efff67248482, androidx.camera.core.Preview-91464e5c-8831-4aa5-b269-f8ad4b4b0b7c248335614, androidx.camera.core.ImageAnalysis-03c9c5f5-ee0b-4640-8564-af627c4166c681050544] for camera: 0
D/SyncCaptureSessionBase(25579): [androidx.camera.camera2.internal.SynchronizedCaptureSessionBaseImpl@1b33782] getSurface...done
D/CaptureSession(25579): Opening capture session.
D/DeferrableSurface(25579): use count+1, useCount=2 androidx.camera.core.SurfaceRequest$2@f56169d
D/DeferrableSurface(25579): New surface in use[total_surfaces=4, used_surfaces=2](androidx.camera.core.impl.ImmediateSurface@476763f}
D/DeferrableSurface(25579): use count+1, useCount=1 androidx.camera.core.impl.ImmediateSurface@476763f
D/DeferrableSurface(25579): New surface in use[total_surfaces=4, used_surfaces=3](androidx.camera.core.impl.ImmediateSurface@d727c55}
D/DeferrableSurface(25579): use count+1, useCount=1 androidx.camera.core.impl.ImmediateSurface@d727c55
D/CaptureSession(25579): Attempting to send capture request onConfigured
D/CaptureSession(25579): Issuing request for session.
D/Camera2CaptureRequestBuilder(25579): createCaptureRequest
D/CaptureSession(25579): CameraCaptureSession.onConfigured() mState=OPENED
D/CaptureSession(25579): CameraCaptureSession.onReady() OPENED
```


Logs on run
```console
Performing hot restart...
Syncing files to device Android SDK built for arm64...
Restarted application in 1,177ms.
D/CameraOrientationUtil(25579): getRelativeImageRotation: destRotationDegrees=0, sourceRotationDegrees=90, isOppositeFacing=true, result=90
D/CameraOrientationUtil(25579): getRelativeImageRotation: destRotationDegrees=0, sourceRotationDegrees=90, isOppositeFacing=false, result=90
I/flutter (25579): Selecting new camera: Camera 0
D/DeferrableSurface(25579): surface closed,  useCount=2 closed=true androidx.camera.core.SurfaceRequest$2@f56169d
D/DeferrableSurface(25579): surface closed,  useCount=0 closed=true androidx.camera.core.processing.SurfaceEdge$SettableSurface@f078561
D/DeferrableSurface(25579): Surface terminated[total_surfaces=3, used_surfaces=3](androidx.camera.core.processing.SurfaceEdge$SettableSurface@f078561}
D/DeferrableSurface(25579): use count-1,  useCount=1 closed=true androidx.camera.core.SurfaceRequest$2@f56169d
D/TakePictureManager(25579): Issue the next TakePictureRequest.
D/TakePictureManager(25579): No new request.
D/ImageCapture(25579): clearPipeline
D/DeferrableSurface(25579): surface closed,  useCount=1 closed=true androidx.camera.core.impl.ImmediateSurface@476763f
D/DeferrableSurface(25579): surface closed,  useCount=1 closed=true androidx.camera.core.impl.ImmediateSurface@d727c55
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Use cases [androidx.camera.core.Preview-91464e5c-8831-4aa5-b269-f8ad4b4b0b7c248335614, androidx.camera.core.ImageCapture-cf6e2bfe-40b0-4baa-bd0c-e81950c3efff67248482, androidx.camera.core.ImageAnalysis-03c9c5f5-ee0b-4640-8564-af627c4166c681050544] now DETACHED for camera
D/UseCaseAttachState(25579): All use case: [] for camera: 0
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Resetting Capture Session
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Releasing session in state OPENED
D/UseCaseAttachState(25579): Active and attached use case: [] for camera: 0
D/UseCaseAttachState(25579): Active and attached use case: [] for camera: 0
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Closing camera.
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Transitioning camera internal state: OPENED --> CLOSING
D/CameraStateRegistry(25579): Recalculating open cameras:
D/CameraStateRegistry(25579): Camera                                       State                 
D/CameraStateRegistry(25579): -------------------------------------------------------------------
D/CameraStateRegistry(25579): Camera@2c97479[id=0]                         CLOSING               
D/CameraStateRegistry(25579): Camera@1a2853b[id=1]                         UNKNOWN               
D/CameraStateRegistry(25579): -------------------------------------------------------------------
D/CameraStateRegistry(25579): Open count: 1 (Max allowed: 1)
D/CameraStateMachine(25579): New public camera state CameraState{type=CLOSING, error=null} from CLOSING and null
D/CameraStateMachine(25579): Publishing new public camera state CameraState{type=CLOSING, error=null}
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Resetting Capture Session
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Releasing session in state CLOSING
E/ObserverFlutterApi(25579): The Observer that received a callback has been garbage collected. Please create a new instance to receive any further data changes.
D/CaptureSession(25579): onSessionFinished()
E/ObserverFlutterApi(25579): The Observer that received a callback has been garbage collected. Please create a new instance to receive any further data changes.
E/ObserverFlutterApi(25579): The Observer that received a callback has been garbage collected. Please create a new instance to receive any further data changes.
D/CameraOrientationUtil(25579): getRelativeImageRotation: destRotationDegrees=0, sourceRotationDegrees=90, isOppositeFacing=true, result=90
I/chatty  (25579): uid=10149(com.fws.plantsnap2) identical 3 lines
D/CameraOrientationUtil(25579): getRelativeImageRotation: destRotationDegrees=0, sourceRotationDegrees=90, isOppositeFacing=true, result=90
D/DynamicRangeResolver(25579): Resolved dynamic range for use case androidx.camera.core.Preview-eadfc831-cb6c-4dd7-8e73-9efa48312445 to no compatible HDR dynamic ranges.
D/DynamicRangeResolver(25579): DynamicRange@bcd3ec4{encoding=UNSPECIFIED, bitDepth=0}
D/DynamicRangeResolver(25579): ->
D/DynamicRangeResolver(25579): DynamicRange@b355d7{encoding=SDR, bitDepth=8}
D/CameraOrientationUtil(25579): getRelativeImageRotation: destRotationDegrees=0, sourceRotationDegrees=90, isOppositeFacing=true, result=90
D/DeferrableSurface(25579): Surface created[total_surfaces=4, used_surfaces=3](androidx.camera.core.processing.SurfaceEdge$SettableSurface@81ff6db}
D/DeferrableSurface(25579): Surface created[total_surfaces=5, used_surfaces=3](androidx.camera.core.SurfaceRequest$2@f1d25b7}
D/DeferrableSurface(25579): New surface in use[total_surfaces=5, used_surfaces=4](androidx.camera.core.SurfaceRequest$2@f1d25b7}
D/DeferrableSurface(25579): use count+1, useCount=1 androidx.camera.core.SurfaceRequest$2@f1d25b7
D/CameraOrientationUtil(25579): getRelativeImageRotation: destRotationDegrees=0, sourceRotationDegrees=90, isOppositeFacing=true, result=90
D/ImageCapture(25579): createPipeline(cameraId: 0, streamSpec: StreamSpec{resolution=640x480, dynamicRange=DynamicRange@b355d7{encoding=SDR, bitDepth=8}, expectedFrameRateRange=[0, 0], implementationOptions=androidx.camera.camera2.impl.Camera2ImplConfig@f4f0b90})
D/DeferrableSurface(25579): Surface created[total_surfaces=6, used_surfaces=4](androidx.camera.core.impl.ImmediateSurface@b8dfc89}
D/CameraOrientationUtil(25579): getRelativeImageRotation: destRotationDegrees=0, sourceRotationDegrees=90, isOppositeFacing=true, result=90
D/CameraOrientationUtil(25579): getRelativeImageRotation: destRotationDegrees=0, sourceRotationDegrees=90, isOppositeFacing=true, result=90
D/DeferrableSurface(25579): Surface created[total_surfaces=7, used_surfaces=4](androidx.camera.core.impl.ImmediateSurface@bb514af}
D/CameraOrientationUtil(25579): getRelativeImageRotation: destRotationDegrees=0, sourceRotationDegrees=90, isOppositeFacing=true, result=90
I/flutter (25579): Camera initialized
D/UseCaseAttachState(25579): Active and attached use case: [] for camera: 0
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Use case androidx.camera.core.ImageCapture-258c2833-e326-4dbf-86e8-0163b61f791b70316788 ACTIVE
D/UseCaseAttachState(25579): Active and attached use case: [] for camera: 0
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Use case androidx.camera.core.Preview-eadfc831-cb6c-4dd7-8e73-9efa4831244562993712 ACTIVE
D/UseCaseAttachState(25579): Active and attached use case: [] for camera: 0
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Use case androidx.camera.core.ImageCapture-258c2833-e326-4dbf-86e8-0163b61f791b70316788 ACTIVE
D/UseCaseAttachState(25579): Active and attached use case: [] for camera: 0
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Use case androidx.camera.core.ImageAnalysis-3ad8de42-27cc-46d4-9bea-a334fbd9127075400338 INACTIVE
D/UseCaseAttachState(25579): Active and attached use case: [] for camera: 0
D/UseCaseAttachState(25579): Active and attached use case: [] for camera: 0
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Use cases [androidx.camera.core.Preview-eadfc831-cb6c-4dd7-8e73-9efa4831244562993712, androidx.camera.core.ImageCapture-258c2833-e326-4dbf-86e8-0163b61f791b70316788, androidx.camera.core.ImageAnalysis-3ad8de42-27cc-46d4-9bea-a334fbd9127075400338] now ATTACHED
D/UseCaseAttachState(25579): All use case: [androidx.camera.core.ImageCapture-258c2833-e326-4dbf-86e8-0163b61f791b70316788, androidx.camera.core.Preview-eadfc831-cb6c-4dd7-8e73-9efa4831244562993712, androidx.camera.core.ImageAnalysis-3ad8de42-27cc-46d4-9bea-a334fbd9127075400338] for camera: 0
D/UseCaseAttachState(25579): Active and attached use case: [androidx.camera.core.ImageCapture-258c2833-e326-4dbf-86e8-0163b61f791b70316788, androidx.camera.core.Preview-eadfc831-cb6c-4dd7-8e73-9efa4831244562993712] for camera: 0
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Resetting Capture Session
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Releasing session in state CLOSING
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Transitioning camera internal state: CLOSING --> REOPENING
D/CameraStateRegistry(25579): Recalculating open cameras:
D/CameraStateRegistry(25579): Camera                                       State                 
D/CameraStateRegistry(25579): -------------------------------------------------------------------
D/CameraStateRegistry(25579): Camera@2c97479[id=0]                         OPENING               
D/CameraStateRegistry(25579): Camera@1a2853b[id=1]                         UNKNOWN               
D/CameraStateRegistry(25579): -------------------------------------------------------------------
D/CameraStateRegistry(25579): Open count: 1 (Max allowed: 1)
D/CameraStateMachine(25579): New public camera state CameraState{type=OPENING, error=null} from OPENING and null
D/CameraStateMachine(25579): Publishing new public camera state CameraState{type=OPENING, error=null}
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Use case androidx.camera.core.Preview-eadfc831-cb6c-4dd7-8e73-9efa4831244562993712 ACTIVE
E/ObserverFlutterApi(25579): The Observer that received a callback has been garbage collected. Please create a new instance to receive any further data changes.
I/chatty  (25579): uid=10149(com.fws.plantsnap2) identical 1 line
E/ObserverFlutterApi(25579): The Observer that received a callback has been garbage collected. Please create a new instance to receive any further data changes.
D/UseCaseAttachState(25579): Active and attached use case: [androidx.camera.core.ImageCapture-258c2833-e326-4dbf-86e8-0163b61f791b70316788, androidx.camera.core.Preview-eadfc831-cb6c-4dd7-8e73-9efa4831244562993712] for camera: 0
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Use case androidx.camera.core.ImageCapture-258c2833-e326-4dbf-86e8-0163b61f791b70316788 ACTIVE
D/UseCaseAttachState(25579): Active and attached use case: [androidx.camera.core.ImageCapture-258c2833-e326-4dbf-86e8-0163b61f791b70316788, androidx.camera.core.Preview-eadfc831-cb6c-4dd7-8e73-9efa4831244562993712] for camera: 0
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Use case androidx.camera.core.ImageAnalysis-3ad8de42-27cc-46d4-9bea-a334fbd9127075400338 INACTIVE
D/UseCaseAttachState(25579): Active and attached use case: [androidx.camera.core.ImageCapture-258c2833-e326-4dbf-86e8-0163b61f791b70316788, androidx.camera.core.Preview-eadfc831-cb6c-4dd7-8e73-9efa4831244562993712] for camera: 0
D/DeferrableSurface(25579): use count-1,  useCount=0 closed=true androidx.camera.core.SurfaceRequest$2@f56169d
D/DeferrableSurface(25579): Surface no longer in use[total_surfaces=7, used_surfaces=3](androidx.camera.core.SurfaceRequest$2@f56169d}
D/DeferrableSurface(25579): Surface terminated[total_surfaces=6, used_surfaces=3](androidx.camera.core.SurfaceRequest$2@f56169d}
D/DeferrableSurface(25579): use count-1,  useCount=0 closed=true androidx.camera.core.impl.ImmediateSurface@476763f
D/DeferrableSurface(25579): Surface no longer in use[total_surfaces=6, used_surfaces=2](androidx.camera.core.impl.ImmediateSurface@476763f}
D/DeferrableSurface(25579): Surface terminated[total_surfaces=5, used_surfaces=2](androidx.camera.core.impl.ImmediateSurface@476763f}
D/DeferrableSurface(25579): use count-1,  useCount=0 closed=true androidx.camera.core.impl.ImmediateSurface@d727c55
D/DeferrableSurface(25579): Surface no longer in use[total_surfaces=5, used_surfaces=1](androidx.camera.core.impl.ImmediateSurface@d727c55}
D/DeferrableSurface(25579): Surface terminated[total_surfaces=4, used_surfaces=1](androidx.camera.core.impl.ImmediateSurface@d727c55}
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} CameraDevice.onClosed()
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Attempting to open the camera.
D/CameraStateRegistry(25579): tryOpenCamera(Camera@2c97479[id=0]) [Available Cameras: 0, Already Open: true (Previous state: OPENING)] --> SUCCESS
D/CameraStateRegistry(25579): Recalculating open cameras:
D/CameraStateRegistry(25579): Camera                                       State                 
D/CameraStateRegistry(25579): -------------------------------------------------------------------
D/CameraStateRegistry(25579): Camera@2c97479[id=0]                         OPENING               
D/CameraStateRegistry(25579): Camera@1a2853b[id=1]                         UNKNOWN               
D/CameraStateRegistry(25579): -------------------------------------------------------------------
D/CameraStateRegistry(25579): Open count: 1 (Max allowed: 1)
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Opening camera.
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Transitioning camera internal state: REOPENING --> OPENING
D/CameraStateMachine(25579): New public camera state CameraState{type=OPENING, error=null} from OPENING and null
D/UseCaseAttachState(25579): All use case: [androidx.camera.core.ImageCapture-258c2833-e326-4dbf-86e8-0163b61f791b70316788, androidx.camera.core.Preview-eadfc831-cb6c-4dd7-8e73-9efa4831244562993712, androidx.camera.core.ImageAnalysis-3ad8de42-27cc-46d4-9bea-a334fbd9127075400338] for camera: 0
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} CameraDevice.onOpened()
D/Camera2CameraImpl(25579): {Camera@2c97479[id=0]} Transitioning camera internal state: OPENING --> OPENED
D/CameraStateRegistry(25579): Recalculating open cameras:
D/CameraStateRegistry(25579): Camera                                       State                 
D/CameraStateRegistry(25579): -------------------------------------------------------------------
D/CameraStateRegistry(25579): Camera@2c97479[id=0]                         OPEN                  
D/CameraStateRegistry(25579): Camera@1a2853b[id=1]                         UNKNOWN               
D/CameraStateRegistry(25579): -------------------------------------------------------------------
D/CameraStateRegistry(25579): Open count: 1 (Max allowed: 1)
D/CameraStateMachine(25579): New public camera state CameraState{type=OPEN, error=null} from OPEN and null
D/CameraStateMachine(25579): Publishing new public camera state CameraState{type=OPEN, error=null}
E/ObserverFlutterApi(25579): The Observer that received a callback has been garbage collected. Please create a new instance to receive any further data changes.
I/chatty  (25579): uid=10149(com.fws.plantsnap2) identical 1 line
E/ObserverFlutterApi(25579): The Observer that received a callback has been garbage collected. Please create a new instance to receive any further data changes.
D/UseCaseAttachState(25579): All use case: [androidx.camera.core.ImageCapture-258c2833-e326-4dbf-86e8-0163b61f791b70316788, androidx.camera.core.Preview-eadfc831-cb6c-4dd7-8e73-9efa4831244562993712, androidx.camera.core.ImageAnalysis-3ad8de42-27cc-46d4-9bea-a334fbd9127075400338] for camera: 0
D/UseCaseAttachState(25579): Active and attached use case: [androidx.camera.core.ImageCapture-258c2833-e326-4dbf-86e8-0163b61f791b70316788, androidx.camera.core.Preview-eadfc831-cb6c-4dd7-8e73-9efa4831244562993712] for camera: 0
D/SyncCaptureSessionBase(25579): [androidx.camera.camera2.internal.SynchronizedCaptureSessionBaseImpl@627af08] getSurface...done
D/CaptureSession(25579): Opening capture session.
D/DeferrableSurface(25579): use count+1, useCount=2 androidx.camera.core.SurfaceRequest$2@f1d25b7
D/DeferrableSurface(25579): New surface in use[total_surfaces=4, used_surfaces=2](androidx.camera.core.impl.ImmediateSurface@b8dfc89}
D/DeferrableSurface(25579): use count+1, useCount=1 androidx.camera.core.impl.ImmediateSurface@b8dfc89
D/DeferrableSurface(25579): New surface in use[total_surfaces=4, used_surfaces=3](androidx.camera.core.impl.ImmediateSurface@bb514af}
D/DeferrableSurface(25579): use count+1, useCount=1 androidx.camera.core.impl.ImmediateSurface@bb514af
D/CaptureSession(25579): Attempting to send capture request onConfigured
D/CaptureSession(25579): Issuing request for session.
D/Camera2CaptureRequestBuilder(25579): createCaptureRequest
D/CaptureSession(25579): CameraCaptureSession.onConfigured() mState=OPENED
D/CaptureSession(25579): CameraCaptureSession.onReady() OPENED
```
</details>


### Flutter Doctor output

<details open><summary>Doctor output</summary>

```console
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.22.0, on macOS 14.5 23F79 darwin-arm64, locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
[✓] Android Studio (version 2024.1)
[✓] IntelliJ IDEA Community Edition (version 2022.1)
[✓] VS Code (version 1.92.0)
[✓] Connected device (3 available)
[✓] Network resources

• No issues found!
```

</details>