[camera] Update Android Camera Access Permission Error Codes (#5640)

diff --git a/packages/camera/camera_android/CHANGELOG.md b/packages/camera/camera_android/CHANGELOG.md
index e3899c3..3a74334 100644
--- a/packages/camera/camera_android/CHANGELOG.md
+++ b/packages/camera/camera_android/CHANGELOG.md
@@ -1,5 +1,6 @@
-## NEXT
+## 0.10.0
 
+* **Breaking Change** Updates Android camera access permission error codes to be consistent with other platforms. If your app still handles the legacy `cameraPermission` exception, please update it to handle the new permission exception codes that are noted in the README.
 * Ignores missing return warnings in preparation for [upcoming analysis changes](https://github.com/flutter/flutter/issues/105750).
 
 ## 0.9.8+3
diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraPermissions.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraPermissions.java
index 7d60e0f..4441751 100644
--- a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraPermissions.java
+++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraPermissions.java
@@ -23,8 +23,22 @@
     void onResult(String errorCode, String errorDescription);
   }
 
+  /**
+   * Camera access permission errors handled when camera is created. See {@code MethodChannelCamera}
+   * in {@code camera/camera_platform_interface} for details.
+   */
+  private static final String CAMERA_PERMISSIONS_REQUEST_ONGOING =
+      "CameraPermissionsRequestOngoing";
+
+  private static final String CAMERA_PERMISSIONS_REQUEST_ONGOING_MESSAGE =
+      "Another request is ongoing and multiple requests cannot be handled at once.";
+  private static final String CAMERA_ACCESS_DENIED = "CameraAccessDenied";
+  private static final String CAMERA_ACCESS_DENIED_MESSAGE = "Camera access permission was denied.";
+  private static final String AUDIO_ACCESS_DENIED = "AudioAccessDenied";
+  private static final String AUDIO_ACCESS_DENIED_MESSAGE = "Audio access permission was denied.";
+
   private static final int CAMERA_REQUEST_ID = 9796;
-  private boolean ongoing = false;
+  @VisibleForTesting boolean ongoing = false;
 
   void requestPermissions(
       Activity activity,
@@ -32,7 +46,9 @@
       boolean enableAudio,
       ResultCallback callback) {
     if (ongoing) {
-      callback.onResult("cameraPermission", "Camera permission request ongoing");
+      callback.onResult(
+          CAMERA_PERMISSIONS_REQUEST_ONGOING, CAMERA_PERMISSIONS_REQUEST_ONGOING_MESSAGE);
+      return;
     }
     if (!hasCameraPermission(activity) || (enableAudio && !hasAudioPermission(activity))) {
       permissionsRegistry.addListener(
@@ -90,9 +106,9 @@
 
       alreadyCalled = true;
       if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
-        callback.onResult("cameraPermission", "MediaRecorderCamera permission not granted");
+        callback.onResult(CAMERA_ACCESS_DENIED, CAMERA_ACCESS_DENIED_MESSAGE);
       } else if (grantResults.length > 1 && grantResults[1] != PackageManager.PERMISSION_GRANTED) {
-        callback.onResult("cameraPermission", "MediaRecorderAudio permission not granted");
+        callback.onResult(AUDIO_ACCESS_DENIED, AUDIO_ACCESS_DENIED_MESSAGE);
       } else {
         callback.onResult(null, null);
       }
diff --git a/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraPermissionsTest.java b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraPermissionsTest.java
index ecb96a8..d734a63 100644
--- a/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraPermissionsTest.java
+++ b/packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraPermissionsTest.java
@@ -5,9 +5,13 @@
 package io.flutter.plugins.camera;
 
 import static junit.framework.TestCase.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
 
 import android.content.pm.PackageManager;
 import io.flutter.plugins.camera.CameraPermissions.CameraRequestPermissionsListener;
+import io.flutter.plugins.camera.CameraPermissions.ResultCallback;
 import org.junit.Test;
 
 public class CameraPermissionsTest {
@@ -24,4 +28,48 @@
 
     assertEquals(1, calledCounter[0]);
   }
+
+  @Test
+  public void callback_respondsWithCameraAccessDenied() {
+    ResultCallback fakeResultCallback = mock(ResultCallback.class);
+    CameraRequestPermissionsListener permissionsListener =
+        new CameraRequestPermissionsListener(fakeResultCallback);
+
+    permissionsListener.onRequestPermissionsResult(
+        9796, null, new int[] {PackageManager.PERMISSION_DENIED});
+
+    verify(fakeResultCallback)
+        .onResult("CameraAccessDenied", "Camera access permission was denied.");
+  }
+
+  @Test
+  public void callback_respondsWithAudioAccessDenied() {
+    ResultCallback fakeResultCallback = mock(ResultCallback.class);
+    CameraRequestPermissionsListener permissionsListener =
+        new CameraRequestPermissionsListener(fakeResultCallback);
+
+    permissionsListener.onRequestPermissionsResult(
+        9796,
+        null,
+        new int[] {PackageManager.PERMISSION_GRANTED, PackageManager.PERMISSION_DENIED});
+
+    verify(fakeResultCallback).onResult("AudioAccessDenied", "Audio access permission was denied.");
+  }
+
+  @Test
+  public void callback_doesNotRespond() {
+    ResultCallback fakeResultCallback = mock(ResultCallback.class);
+    CameraRequestPermissionsListener permissionsListener =
+        new CameraRequestPermissionsListener(fakeResultCallback);
+
+    permissionsListener.onRequestPermissionsResult(
+        9796,
+        null,
+        new int[] {PackageManager.PERMISSION_GRANTED, PackageManager.PERMISSION_GRANTED});
+
+    verify(fakeResultCallback, never())
+        .onResult("CameraAccessDenied", "Camera access permission was denied.");
+    verify(fakeResultCallback, never())
+        .onResult("AudioAccessDenied", "Audio access permission was denied.");
+  }
 }
diff --git a/packages/camera/camera_android/pubspec.yaml b/packages/camera/camera_android/pubspec.yaml
index a1b7a93..581780f 100644
--- a/packages/camera/camera_android/pubspec.yaml
+++ b/packages/camera/camera_android/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Android implementation of the camera plugin.
 repository: https://github.com/flutter/plugins/tree/main/packages/camera/camera_android
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
-version: 0.9.8+3
+version: 0.10.0
 
 environment:
   sdk: ">=2.14.0 <3.0.0"