diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/GeneratedCameraXLibrary.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/GeneratedCameraXLibrary.java
index e7f7cae..4d4439e 100644
--- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/GeneratedCameraXLibrary.java
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/GeneratedCameraXLibrary.java
@@ -1,7 +1,7 @@
 // Copyright 2013 The Flutter Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
-// Autogenerated from Pigeon (v3.2.9), do not edit directly.
+// Autogenerated from Pigeon (v9.1.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 
 package io.flutter.plugins.camerax;
@@ -17,16 +17,48 @@
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
+import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 
 /** Generated class from Pigeon. */
-@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression"})
+@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression", "serial"})
 public class GeneratedCameraXLibrary {
 
+  /** Error class for passing custom error details to Flutter via a thrown PlatformException. */
+  public static class FlutterError extends RuntimeException {
+
+    /** The error code. */
+    public final String code;
+
+    /** The error details. Must be a datatype supported by the api codec. */
+    public final Object details;
+
+    public FlutterError(@NonNull String code, @Nullable String message, @Nullable Object details) {
+      super(message);
+      this.code = code;
+      this.details = details;
+    }
+  }
+
+  @NonNull
+  private static ArrayList<Object> wrapError(@NonNull Throwable exception) {
+    ArrayList<Object> errorList = new ArrayList<Object>(3);
+    if (exception instanceof FlutterError) {
+      FlutterError error = (FlutterError) exception;
+      errorList.add(error.code);
+      errorList.add(error.getMessage());
+      errorList.add(error.details);
+    } else {
+      errorList.add(exception.toString());
+      errorList.add(exception.getClass().getSimpleName());
+      errorList.add(
+          "Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception));
+    }
+    return errorList;
+  }
+
   /** Generated class from Pigeon that represents data sent in messages. */
-  public static class ResolutionInfo {
+  public static final class ResolutionInfo {
     private @NonNull Long width;
 
     public @NonNull Long getWidth() {
@@ -57,6 +89,7 @@
     private ResolutionInfo() {}
 
     public static final class Builder {
+
       private @Nullable Long width;
 
       public @NonNull Builder setWidth(@NonNull Long setterArg) {
@@ -80,19 +113,19 @@
     }
 
     @NonNull
-    Map<String, Object> toMap() {
-      Map<String, Object> toMapResult = new HashMap<>();
-      toMapResult.put("width", width);
-      toMapResult.put("height", height);
-      return toMapResult;
+    ArrayList<Object> toList() {
+      ArrayList<Object> toListResult = new ArrayList<Object>(2);
+      toListResult.add(width);
+      toListResult.add(height);
+      return toListResult;
     }
 
-    static @NonNull ResolutionInfo fromMap(@NonNull Map<String, Object> map) {
+    static @NonNull ResolutionInfo fromList(@NonNull ArrayList<Object> list) {
       ResolutionInfo pigeonResult = new ResolutionInfo();
-      Object width = map.get("width");
+      Object width = list.get(0);
       pigeonResult.setWidth(
           (width == null) ? null : ((width instanceof Integer) ? (Integer) width : (Long) width));
-      Object height = map.get("height");
+      Object height = list.get(1);
       pigeonResult.setHeight(
           (height == null)
               ? null
@@ -102,7 +135,7 @@
   }
 
   /** Generated class from Pigeon that represents data sent in messages. */
-  public static class CameraPermissionsErrorData {
+  public static final class CameraPermissionsErrorData {
     private @NonNull String errorCode;
 
     public @NonNull String getErrorCode() {
@@ -133,6 +166,7 @@
     private CameraPermissionsErrorData() {}
 
     public static final class Builder {
+
       private @Nullable String errorCode;
 
       public @NonNull Builder setErrorCode(@NonNull String setterArg) {
@@ -156,18 +190,18 @@
     }
 
     @NonNull
-    Map<String, Object> toMap() {
-      Map<String, Object> toMapResult = new HashMap<>();
-      toMapResult.put("errorCode", errorCode);
-      toMapResult.put("description", description);
-      return toMapResult;
+    ArrayList<Object> toList() {
+      ArrayList<Object> toListResult = new ArrayList<Object>(2);
+      toListResult.add(errorCode);
+      toListResult.add(description);
+      return toListResult;
     }
 
-    static @NonNull CameraPermissionsErrorData fromMap(@NonNull Map<String, Object> map) {
+    static @NonNull CameraPermissionsErrorData fromList(@NonNull ArrayList<Object> list) {
       CameraPermissionsErrorData pigeonResult = new CameraPermissionsErrorData();
-      Object errorCode = map.get("errorCode");
+      Object errorCode = list.get(0);
       pigeonResult.setErrorCode((String) errorCode);
-      Object description = map.get("description");
+      Object description = list.get(1);
       pigeonResult.setDescription((String) description);
       return pigeonResult;
     }
@@ -178,22 +212,19 @@
 
     void error(Throwable error);
   }
-
-  private static class InstanceManagerHostApiCodec extends StandardMessageCodec {
-    public static final InstanceManagerHostApiCodec INSTANCE = new InstanceManagerHostApiCodec();
-
-    private InstanceManagerHostApiCodec() {}
-  }
-
   /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
   public interface InstanceManagerHostApi {
+    /**
+     * Clear the native `InstanceManager`.
+     *
+     * <p>This is typically only used after a hot restart.
+     */
     void clear();
 
     /** The codec used by InstanceManagerHostApi. */
     static MessageCodec<Object> getCodec() {
-      return InstanceManagerHostApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
-
     /**
      * Sets up an instance of `InstanceManagerHostApi` to handle messages through the
      * `binaryMessenger`.
@@ -206,12 +237,13 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
                 try {
                   api.clear();
-                  wrapped.put("result", null);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, null);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -221,22 +253,15 @@
       }
     }
   }
-
-  private static class JavaObjectHostApiCodec extends StandardMessageCodec {
-    public static final JavaObjectHostApiCodec INSTANCE = new JavaObjectHostApiCodec();
-
-    private JavaObjectHostApiCodec() {}
-  }
-
   /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
   public interface JavaObjectHostApi {
+
     void dispose(@NonNull Long identifier);
 
     /** The codec used by JavaObjectHostApi. */
     static MessageCodec<Object> getCodec() {
-      return JavaObjectHostApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
-
     /**
      * Sets up an instance of `JavaObjectHostApi` to handle messages through the `binaryMessenger`.
      */
@@ -248,17 +273,15 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                ArrayList<Object> args = (ArrayList<Object>) message;
+                Number identifierArg = (Number) args.get(0);
                 try {
-                  ArrayList<Object> args = (ArrayList<Object>) message;
-                  Number identifierArg = (Number) args.get(0);
-                  if (identifierArg == null) {
-                    throw new NullPointerException("identifierArg unexpectedly null.");
-                  }
                   api.dispose((identifierArg == null) ? null : identifierArg.longValue());
-                  wrapped.put("result", null);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, null);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -268,13 +291,6 @@
       }
     }
   }
-
-  private static class JavaObjectFlutterApiCodec extends StandardMessageCodec {
-    public static final JavaObjectFlutterApiCodec INSTANCE = new JavaObjectFlutterApiCodec();
-
-    private JavaObjectFlutterApiCodec() {}
-  }
-
   /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */
   public static class JavaObjectFlutterApi {
     private final BinaryMessenger binaryMessenger;
@@ -283,12 +299,13 @@
       this.binaryMessenger = argBinaryMessenger;
     }
 
+    /** Public interface for sending reply. */
     public interface Reply<T> {
       void reply(T reply);
     }
-
+    /** The codec used by JavaObjectFlutterApi. */
     static MessageCodec<Object> getCodec() {
-      return JavaObjectFlutterApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
 
     public void dispose(@NonNull Long identifierArg, Reply<Void> callback) {
@@ -296,29 +313,20 @@
           new BasicMessageChannel<>(
               binaryMessenger, "dev.flutter.pigeon.JavaObjectFlutterApi.dispose", getCodec());
       channel.send(
-          new ArrayList<Object>(Arrays.asList(identifierArg)),
-          channelReply -> {
-            callback.reply(null);
-          });
+          new ArrayList<Object>(Collections.singletonList(identifierArg)),
+          channelReply -> callback.reply(null));
     }
   }
-
-  private static class CameraInfoHostApiCodec extends StandardMessageCodec {
-    public static final CameraInfoHostApiCodec INSTANCE = new CameraInfoHostApiCodec();
-
-    private CameraInfoHostApiCodec() {}
-  }
-
   /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
   public interface CameraInfoHostApi {
+
     @NonNull
     Long getSensorRotationDegrees(@NonNull Long identifier);
 
     /** The codec used by CameraInfoHostApi. */
     static MessageCodec<Object> getCodec() {
-      return CameraInfoHostApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
-
     /**
      * Sets up an instance of `CameraInfoHostApi` to handle messages through the `binaryMessenger`.
      */
@@ -332,19 +340,17 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                ArrayList<Object> args = (ArrayList<Object>) message;
+                Number identifierArg = (Number) args.get(0);
                 try {
-                  ArrayList<Object> args = (ArrayList<Object>) message;
-                  Number identifierArg = (Number) args.get(0);
-                  if (identifierArg == null) {
-                    throw new NullPointerException("identifierArg unexpectedly null.");
-                  }
                   Long output =
                       api.getSensorRotationDegrees(
                           (identifierArg == null) ? null : identifierArg.longValue());
-                  wrapped.put("result", output);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, output);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -354,13 +360,6 @@
       }
     }
   }
-
-  private static class CameraInfoFlutterApiCodec extends StandardMessageCodec {
-    public static final CameraInfoFlutterApiCodec INSTANCE = new CameraInfoFlutterApiCodec();
-
-    private CameraInfoFlutterApiCodec() {}
-  }
-
   /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */
   public static class CameraInfoFlutterApi {
     private final BinaryMessenger binaryMessenger;
@@ -369,12 +368,13 @@
       this.binaryMessenger = argBinaryMessenger;
     }
 
+    /** Public interface for sending reply. */
     public interface Reply<T> {
       void reply(T reply);
     }
-
+    /** The codec used by CameraInfoFlutterApi. */
     static MessageCodec<Object> getCodec() {
-      return CameraInfoFlutterApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
 
     public void create(@NonNull Long identifierArg, Reply<Void> callback) {
@@ -382,21 +382,13 @@
           new BasicMessageChannel<>(
               binaryMessenger, "dev.flutter.pigeon.CameraInfoFlutterApi.create", getCodec());
       channel.send(
-          new ArrayList<Object>(Arrays.asList(identifierArg)),
-          channelReply -> {
-            callback.reply(null);
-          });
+          new ArrayList<Object>(Collections.singletonList(identifierArg)),
+          channelReply -> callback.reply(null));
     }
   }
-
-  private static class CameraSelectorHostApiCodec extends StandardMessageCodec {
-    public static final CameraSelectorHostApiCodec INSTANCE = new CameraSelectorHostApiCodec();
-
-    private CameraSelectorHostApiCodec() {}
-  }
-
   /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
   public interface CameraSelectorHostApi {
+
     void create(@NonNull Long identifier, @Nullable Long lensFacing);
 
     @NonNull
@@ -404,9 +396,8 @@
 
     /** The codec used by CameraSelectorHostApi. */
     static MessageCodec<Object> getCodec() {
-      return CameraSelectorHostApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
-
     /**
      * Sets up an instance of `CameraSelectorHostApi` to handle messages through the
      * `binaryMessenger`.
@@ -419,20 +410,18 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                ArrayList<Object> args = (ArrayList<Object>) message;
+                Number identifierArg = (Number) args.get(0);
+                Number lensFacingArg = (Number) args.get(1);
                 try {
-                  ArrayList<Object> args = (ArrayList<Object>) message;
-                  Number identifierArg = (Number) args.get(0);
-                  if (identifierArg == null) {
-                    throw new NullPointerException("identifierArg unexpectedly null.");
-                  }
-                  Number lensFacingArg = (Number) args.get(1);
                   api.create(
                       (identifierArg == null) ? null : identifierArg.longValue(),
                       (lensFacingArg == null) ? null : lensFacingArg.longValue());
-                  wrapped.put("result", null);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, null);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -447,24 +436,19 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                ArrayList<Object> args = (ArrayList<Object>) message;
+                Number identifierArg = (Number) args.get(0);
+                List<Long> cameraInfoIdsArg = (List<Long>) args.get(1);
                 try {
-                  ArrayList<Object> args = (ArrayList<Object>) message;
-                  Number identifierArg = (Number) args.get(0);
-                  if (identifierArg == null) {
-                    throw new NullPointerException("identifierArg unexpectedly null.");
-                  }
-                  List<Long> cameraInfoIdsArg = (List<Long>) args.get(1);
-                  if (cameraInfoIdsArg == null) {
-                    throw new NullPointerException("cameraInfoIdsArg unexpectedly null.");
-                  }
                   List<Long> output =
                       api.filter(
                           (identifierArg == null) ? null : identifierArg.longValue(),
                           cameraInfoIdsArg);
-                  wrapped.put("result", output);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, output);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -474,14 +458,6 @@
       }
     }
   }
-
-  private static class CameraSelectorFlutterApiCodec extends StandardMessageCodec {
-    public static final CameraSelectorFlutterApiCodec INSTANCE =
-        new CameraSelectorFlutterApiCodec();
-
-    private CameraSelectorFlutterApiCodec() {}
-  }
-
   /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */
   public static class CameraSelectorFlutterApi {
     private final BinaryMessenger binaryMessenger;
@@ -490,12 +466,13 @@
       this.binaryMessenger = argBinaryMessenger;
     }
 
+    /** Public interface for sending reply. */
     public interface Reply<T> {
       void reply(T reply);
     }
-
+    /** The codec used by CameraSelectorFlutterApi. */
     static MessageCodec<Object> getCodec() {
-      return CameraSelectorFlutterApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
 
     public void create(
@@ -505,21 +482,12 @@
               binaryMessenger, "dev.flutter.pigeon.CameraSelectorFlutterApi.create", getCodec());
       channel.send(
           new ArrayList<Object>(Arrays.asList(identifierArg, lensFacingArg)),
-          channelReply -> {
-            callback.reply(null);
-          });
+          channelReply -> callback.reply(null));
     }
   }
-
-  private static class ProcessCameraProviderHostApiCodec extends StandardMessageCodec {
-    public static final ProcessCameraProviderHostApiCodec INSTANCE =
-        new ProcessCameraProviderHostApiCodec();
-
-    private ProcessCameraProviderHostApiCodec() {}
-  }
-
   /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
   public interface ProcessCameraProviderHostApi {
+
     void getInstance(Result<Long> result);
 
     @NonNull
@@ -540,9 +508,8 @@
 
     /** The codec used by ProcessCameraProviderHostApi. */
     static MessageCodec<Object> getCodec() {
-      return ProcessCameraProviderHostApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
-
     /**
      * Sets up an instance of `ProcessCameraProviderHostApi` to handle messages through the
      * `binaryMessenger`.
@@ -557,26 +524,21 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
-                try {
-                  Result<Long> resultCallback =
-                      new Result<Long>() {
-                        public void success(Long result) {
-                          wrapped.put("result", result);
-                          reply.reply(wrapped);
-                        }
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                Result<Long> resultCallback =
+                    new Result<Long>() {
+                      public void success(Long result) {
+                        wrapped.add(0, result);
+                        reply.reply(wrapped);
+                      }
 
-                        public void error(Throwable error) {
-                          wrapped.put("error", wrapError(error));
-                          reply.reply(wrapped);
-                        }
-                      };
+                      public void error(Throwable error) {
+                        ArrayList<Object> wrappedError = wrapError(error);
+                        reply.reply(wrappedError);
+                      }
+                    };
 
-                  api.getInstance(resultCallback);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
-                  reply.reply(wrapped);
-                }
+                api.getInstance(resultCallback);
               });
         } else {
           channel.setMessageHandler(null);
@@ -591,19 +553,17 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                ArrayList<Object> args = (ArrayList<Object>) message;
+                Number identifierArg = (Number) args.get(0);
                 try {
-                  ArrayList<Object> args = (ArrayList<Object>) message;
-                  Number identifierArg = (Number) args.get(0);
-                  if (identifierArg == null) {
-                    throw new NullPointerException("identifierArg unexpectedly null.");
-                  }
                   List<Long> output =
                       api.getAvailableCameraInfos(
                           (identifierArg == null) ? null : identifierArg.longValue());
-                  wrapped.put("result", output);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, output);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -620,22 +580,12 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                ArrayList<Object> args = (ArrayList<Object>) message;
+                Number identifierArg = (Number) args.get(0);
+                Number cameraSelectorIdentifierArg = (Number) args.get(1);
+                List<Long> useCaseIdsArg = (List<Long>) args.get(2);
                 try {
-                  ArrayList<Object> args = (ArrayList<Object>) message;
-                  Number identifierArg = (Number) args.get(0);
-                  if (identifierArg == null) {
-                    throw new NullPointerException("identifierArg unexpectedly null.");
-                  }
-                  Number cameraSelectorIdentifierArg = (Number) args.get(1);
-                  if (cameraSelectorIdentifierArg == null) {
-                    throw new NullPointerException(
-                        "cameraSelectorIdentifierArg unexpectedly null.");
-                  }
-                  List<Long> useCaseIdsArg = (List<Long>) args.get(2);
-                  if (useCaseIdsArg == null) {
-                    throw new NullPointerException("useCaseIdsArg unexpectedly null.");
-                  }
                   Long output =
                       api.bindToLifecycle(
                           (identifierArg == null) ? null : identifierArg.longValue(),
@@ -643,9 +593,10 @@
                               ? null
                               : cameraSelectorIdentifierArg.longValue(),
                           useCaseIdsArg);
-                  wrapped.put("result", output);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, output);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -662,24 +613,19 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                ArrayList<Object> args = (ArrayList<Object>) message;
+                Number identifierArg = (Number) args.get(0);
+                Number useCaseIdentifierArg = (Number) args.get(1);
                 try {
-                  ArrayList<Object> args = (ArrayList<Object>) message;
-                  Number identifierArg = (Number) args.get(0);
-                  if (identifierArg == null) {
-                    throw new NullPointerException("identifierArg unexpectedly null.");
-                  }
-                  Number useCaseIdentifierArg = (Number) args.get(1);
-                  if (useCaseIdentifierArg == null) {
-                    throw new NullPointerException("useCaseIdentifierArg unexpectedly null.");
-                  }
                   Boolean output =
                       api.isBound(
                           (identifierArg == null) ? null : identifierArg.longValue(),
                           (useCaseIdentifierArg == null) ? null : useCaseIdentifierArg.longValue());
-                  wrapped.put("result", output);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, output);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -696,22 +642,17 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                ArrayList<Object> args = (ArrayList<Object>) message;
+                Number identifierArg = (Number) args.get(0);
+                List<Long> useCaseIdsArg = (List<Long>) args.get(1);
                 try {
-                  ArrayList<Object> args = (ArrayList<Object>) message;
-                  Number identifierArg = (Number) args.get(0);
-                  if (identifierArg == null) {
-                    throw new NullPointerException("identifierArg unexpectedly null.");
-                  }
-                  List<Long> useCaseIdsArg = (List<Long>) args.get(1);
-                  if (useCaseIdsArg == null) {
-                    throw new NullPointerException("useCaseIdsArg unexpectedly null.");
-                  }
                   api.unbind(
                       (identifierArg == null) ? null : identifierArg.longValue(), useCaseIdsArg);
-                  wrapped.put("result", null);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, null);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -728,17 +669,15 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                ArrayList<Object> args = (ArrayList<Object>) message;
+                Number identifierArg = (Number) args.get(0);
                 try {
-                  ArrayList<Object> args = (ArrayList<Object>) message;
-                  Number identifierArg = (Number) args.get(0);
-                  if (identifierArg == null) {
-                    throw new NullPointerException("identifierArg unexpectedly null.");
-                  }
                   api.unbindAll((identifierArg == null) ? null : identifierArg.longValue());
-                  wrapped.put("result", null);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, null);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -748,14 +687,6 @@
       }
     }
   }
-
-  private static class ProcessCameraProviderFlutterApiCodec extends StandardMessageCodec {
-    public static final ProcessCameraProviderFlutterApiCodec INSTANCE =
-        new ProcessCameraProviderFlutterApiCodec();
-
-    private ProcessCameraProviderFlutterApiCodec() {}
-  }
-
   /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */
   public static class ProcessCameraProviderFlutterApi {
     private final BinaryMessenger binaryMessenger;
@@ -764,12 +695,13 @@
       this.binaryMessenger = argBinaryMessenger;
     }
 
+    /** Public interface for sending reply. */
     public interface Reply<T> {
       void reply(T reply);
     }
-
+    /** The codec used by ProcessCameraProviderFlutterApi. */
     static MessageCodec<Object> getCodec() {
-      return ProcessCameraProviderFlutterApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
 
     public void create(@NonNull Long identifierArg, Reply<Void> callback) {
@@ -779,19 +711,10 @@
               "dev.flutter.pigeon.ProcessCameraProviderFlutterApi.create",
               getCodec());
       channel.send(
-          new ArrayList<Object>(Arrays.asList(identifierArg)),
-          channelReply -> {
-            callback.reply(null);
-          });
+          new ArrayList<Object>(Collections.singletonList(identifierArg)),
+          channelReply -> callback.reply(null));
     }
   }
-
-  private static class CameraFlutterApiCodec extends StandardMessageCodec {
-    public static final CameraFlutterApiCodec INSTANCE = new CameraFlutterApiCodec();
-
-    private CameraFlutterApiCodec() {}
-  }
-
   /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */
   public static class CameraFlutterApi {
     private final BinaryMessenger binaryMessenger;
@@ -800,12 +723,13 @@
       this.binaryMessenger = argBinaryMessenger;
     }
 
+    /** Public interface for sending reply. */
     public interface Reply<T> {
       void reply(T reply);
     }
-
+    /** The codec used by CameraFlutterApi. */
     static MessageCodec<Object> getCodec() {
-      return CameraFlutterApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
 
     public void create(@NonNull Long identifierArg, Reply<Void> callback) {
@@ -813,10 +737,8 @@
           new BasicMessageChannel<>(
               binaryMessenger, "dev.flutter.pigeon.CameraFlutterApi.create", getCodec());
       channel.send(
-          new ArrayList<Object>(Arrays.asList(identifierArg)),
-          channelReply -> {
-            callback.reply(null);
-          });
+          new ArrayList<Object>(Collections.singletonList(identifierArg)),
+          channelReply -> callback.reply(null));
     }
   }
 
@@ -826,21 +748,20 @@
     private SystemServicesHostApiCodec() {}
 
     @Override
-    protected Object readValueOfType(byte type, ByteBuffer buffer) {
+    protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
       switch (type) {
         case (byte) 128:
-          return CameraPermissionsErrorData.fromMap((Map<String, Object>) readValue(buffer));
-
+          return CameraPermissionsErrorData.fromList((ArrayList<Object>) readValue(buffer));
         default:
           return super.readValueOfType(type, buffer);
       }
     }
 
     @Override
-    protected void writeValue(ByteArrayOutputStream stream, Object value) {
+    protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
       if (value instanceof CameraPermissionsErrorData) {
         stream.write(128);
-        writeValue(stream, ((CameraPermissionsErrorData) value).toMap());
+        writeValue(stream, ((CameraPermissionsErrorData) value).toList());
       } else {
         super.writeValue(stream, value);
       }
@@ -849,6 +770,7 @@
 
   /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
   public interface SystemServicesHostApi {
+
     void requestCameraPermissions(
         @NonNull Boolean enableAudio, Result<CameraPermissionsErrorData> result);
 
@@ -861,7 +783,6 @@
     static MessageCodec<Object> getCodec() {
       return SystemServicesHostApiCodec.INSTANCE;
     }
-
     /**
      * Sets up an instance of `SystemServicesHostApi` to handle messages through the
      * `binaryMessenger`.
@@ -876,31 +797,23 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
-                try {
-                  ArrayList<Object> args = (ArrayList<Object>) message;
-                  Boolean enableAudioArg = (Boolean) args.get(0);
-                  if (enableAudioArg == null) {
-                    throw new NullPointerException("enableAudioArg unexpectedly null.");
-                  }
-                  Result<CameraPermissionsErrorData> resultCallback =
-                      new Result<CameraPermissionsErrorData>() {
-                        public void success(CameraPermissionsErrorData result) {
-                          wrapped.put("result", result);
-                          reply.reply(wrapped);
-                        }
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                ArrayList<Object> args = (ArrayList<Object>) message;
+                Boolean enableAudioArg = (Boolean) args.get(0);
+                Result<CameraPermissionsErrorData> resultCallback =
+                    new Result<CameraPermissionsErrorData>() {
+                      public void success(CameraPermissionsErrorData result) {
+                        wrapped.add(0, result);
+                        reply.reply(wrapped);
+                      }
 
-                        public void error(Throwable error) {
-                          wrapped.put("error", wrapError(error));
-                          reply.reply(wrapped);
-                        }
-                      };
+                      public void error(Throwable error) {
+                        ArrayList<Object> wrappedError = wrapError(error);
+                        reply.reply(wrappedError);
+                      }
+                    };
 
-                  api.requestCameraPermissions(enableAudioArg, resultCallback);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
-                  reply.reply(wrapped);
-                }
+                api.requestCameraPermissions(enableAudioArg, resultCallback);
               });
         } else {
           channel.setMessageHandler(null);
@@ -915,23 +828,18 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                ArrayList<Object> args = (ArrayList<Object>) message;
+                Boolean isFrontFacingArg = (Boolean) args.get(0);
+                Number sensorOrientationArg = (Number) args.get(1);
                 try {
-                  ArrayList<Object> args = (ArrayList<Object>) message;
-                  Boolean isFrontFacingArg = (Boolean) args.get(0);
-                  if (isFrontFacingArg == null) {
-                    throw new NullPointerException("isFrontFacingArg unexpectedly null.");
-                  }
-                  Number sensorOrientationArg = (Number) args.get(1);
-                  if (sensorOrientationArg == null) {
-                    throw new NullPointerException("sensorOrientationArg unexpectedly null.");
-                  }
                   api.startListeningForDeviceOrientationChange(
                       isFrontFacingArg,
                       (sensorOrientationArg == null) ? null : sensorOrientationArg.longValue());
-                  wrapped.put("result", null);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, null);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -948,12 +856,13 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
                 try {
                   api.stopListeningForDeviceOrientationChange();
-                  wrapped.put("result", null);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, null);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -963,14 +872,6 @@
       }
     }
   }
-
-  private static class SystemServicesFlutterApiCodec extends StandardMessageCodec {
-    public static final SystemServicesFlutterApiCodec INSTANCE =
-        new SystemServicesFlutterApiCodec();
-
-    private SystemServicesFlutterApiCodec() {}
-  }
-
   /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */
   public static class SystemServicesFlutterApi {
     private final BinaryMessenger binaryMessenger;
@@ -979,12 +880,13 @@
       this.binaryMessenger = argBinaryMessenger;
     }
 
+    /** Public interface for sending reply. */
     public interface Reply<T> {
       void reply(T reply);
     }
-
+    /** The codec used by SystemServicesFlutterApi. */
     static MessageCodec<Object> getCodec() {
-      return SystemServicesFlutterApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
 
     public void onDeviceOrientationChanged(@NonNull String orientationArg, Reply<Void> callback) {
@@ -994,10 +896,8 @@
               "dev.flutter.pigeon.SystemServicesFlutterApi.onDeviceOrientationChanged",
               getCodec());
       channel.send(
-          new ArrayList<Object>(Arrays.asList(orientationArg)),
-          channelReply -> {
-            callback.reply(null);
-          });
+          new ArrayList<Object>(Collections.singletonList(orientationArg)),
+          channelReply -> callback.reply(null));
     }
 
     public void onCameraError(@NonNull String errorDescriptionArg, Reply<Void> callback) {
@@ -1007,10 +907,8 @@
               "dev.flutter.pigeon.SystemServicesFlutterApi.onCameraError",
               getCodec());
       channel.send(
-          new ArrayList<Object>(Arrays.asList(errorDescriptionArg)),
-          channelReply -> {
-            callback.reply(null);
-          });
+          new ArrayList<Object>(Collections.singletonList(errorDescriptionArg)),
+          channelReply -> callback.reply(null));
     }
   }
 
@@ -1020,27 +918,25 @@
     private PreviewHostApiCodec() {}
 
     @Override
-    protected Object readValueOfType(byte type, ByteBuffer buffer) {
+    protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
       switch (type) {
         case (byte) 128:
-          return ResolutionInfo.fromMap((Map<String, Object>) readValue(buffer));
-
+          return ResolutionInfo.fromList((ArrayList<Object>) readValue(buffer));
         case (byte) 129:
-          return ResolutionInfo.fromMap((Map<String, Object>) readValue(buffer));
-
+          return ResolutionInfo.fromList((ArrayList<Object>) readValue(buffer));
         default:
           return super.readValueOfType(type, buffer);
       }
     }
 
     @Override
-    protected void writeValue(ByteArrayOutputStream stream, Object value) {
+    protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
       if (value instanceof ResolutionInfo) {
         stream.write(128);
-        writeValue(stream, ((ResolutionInfo) value).toMap());
+        writeValue(stream, ((ResolutionInfo) value).toList());
       } else if (value instanceof ResolutionInfo) {
         stream.write(129);
-        writeValue(stream, ((ResolutionInfo) value).toMap());
+        writeValue(stream, ((ResolutionInfo) value).toList());
       } else {
         super.writeValue(stream, value);
       }
@@ -1049,6 +945,7 @@
 
   /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
   public interface PreviewHostApi {
+
     void create(
         @NonNull Long identifier,
         @Nullable Long rotation,
@@ -1066,7 +963,6 @@
     static MessageCodec<Object> getCodec() {
       return PreviewHostApiCodec.INSTANCE;
     }
-
     /** Sets up an instance of `PreviewHostApi` to handle messages through the `binaryMessenger`. */
     static void setup(BinaryMessenger binaryMessenger, PreviewHostApi api) {
       {
@@ -1076,22 +972,20 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                ArrayList<Object> args = (ArrayList<Object>) message;
+                Number identifierArg = (Number) args.get(0);
+                Number rotationArg = (Number) args.get(1);
+                ResolutionInfo targetResolutionArg = (ResolutionInfo) args.get(2);
                 try {
-                  ArrayList<Object> args = (ArrayList<Object>) message;
-                  Number identifierArg = (Number) args.get(0);
-                  if (identifierArg == null) {
-                    throw new NullPointerException("identifierArg unexpectedly null.");
-                  }
-                  Number rotationArg = (Number) args.get(1);
-                  ResolutionInfo targetResolutionArg = (ResolutionInfo) args.get(2);
                   api.create(
                       (identifierArg == null) ? null : identifierArg.longValue(),
                       (rotationArg == null) ? null : rotationArg.longValue(),
                       targetResolutionArg);
-                  wrapped.put("result", null);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, null);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -1108,19 +1002,17 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                ArrayList<Object> args = (ArrayList<Object>) message;
+                Number identifierArg = (Number) args.get(0);
                 try {
-                  ArrayList<Object> args = (ArrayList<Object>) message;
-                  Number identifierArg = (Number) args.get(0);
-                  if (identifierArg == null) {
-                    throw new NullPointerException("identifierArg unexpectedly null.");
-                  }
                   Long output =
                       api.setSurfaceProvider(
                           (identifierArg == null) ? null : identifierArg.longValue());
-                  wrapped.put("result", output);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, output);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -1137,12 +1029,13 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
                 try {
                   api.releaseFlutterSurfaceTexture();
-                  wrapped.put("result", null);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, null);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -1157,19 +1050,17 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                ArrayList<Object> args = (ArrayList<Object>) message;
+                Number identifierArg = (Number) args.get(0);
                 try {
-                  ArrayList<Object> args = (ArrayList<Object>) message;
-                  Number identifierArg = (Number) args.get(0);
-                  if (identifierArg == null) {
-                    throw new NullPointerException("identifierArg unexpectedly null.");
-                  }
                   ResolutionInfo output =
                       api.getResolutionInfo(
                           (identifierArg == null) ? null : identifierArg.longValue());
-                  wrapped.put("result", output);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, output);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -1186,21 +1077,20 @@
     private ImageCaptureHostApiCodec() {}
 
     @Override
-    protected Object readValueOfType(byte type, ByteBuffer buffer) {
+    protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
       switch (type) {
         case (byte) 128:
-          return ResolutionInfo.fromMap((Map<String, Object>) readValue(buffer));
-
+          return ResolutionInfo.fromList((ArrayList<Object>) readValue(buffer));
         default:
           return super.readValueOfType(type, buffer);
       }
     }
 
     @Override
-    protected void writeValue(ByteArrayOutputStream stream, Object value) {
+    protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
       if (value instanceof ResolutionInfo) {
         stream.write(128);
-        writeValue(stream, ((ResolutionInfo) value).toMap());
+        writeValue(stream, ((ResolutionInfo) value).toList());
       } else {
         super.writeValue(stream, value);
       }
@@ -1209,6 +1099,7 @@
 
   /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
   public interface ImageCaptureHostApi {
+
     void create(
         @NonNull Long identifier,
         @Nullable Long flashMode,
@@ -1222,7 +1113,6 @@
     static MessageCodec<Object> getCodec() {
       return ImageCaptureHostApiCodec.INSTANCE;
     }
-
     /**
      * Sets up an instance of `ImageCaptureHostApi` to handle messages through the
      * `binaryMessenger`.
@@ -1235,22 +1125,20 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                ArrayList<Object> args = (ArrayList<Object>) message;
+                Number identifierArg = (Number) args.get(0);
+                Number flashModeArg = (Number) args.get(1);
+                ResolutionInfo targetResolutionArg = (ResolutionInfo) args.get(2);
                 try {
-                  ArrayList<Object> args = (ArrayList<Object>) message;
-                  Number identifierArg = (Number) args.get(0);
-                  if (identifierArg == null) {
-                    throw new NullPointerException("identifierArg unexpectedly null.");
-                  }
-                  Number flashModeArg = (Number) args.get(1);
-                  ResolutionInfo targetResolutionArg = (ResolutionInfo) args.get(2);
                   api.create(
                       (identifierArg == null) ? null : identifierArg.longValue(),
                       (flashModeArg == null) ? null : flashModeArg.longValue(),
                       targetResolutionArg);
-                  wrapped.put("result", null);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, null);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -1265,23 +1153,18 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                ArrayList<Object> args = (ArrayList<Object>) message;
+                Number identifierArg = (Number) args.get(0);
+                Number flashModeArg = (Number) args.get(1);
                 try {
-                  ArrayList<Object> args = (ArrayList<Object>) message;
-                  Number identifierArg = (Number) args.get(0);
-                  if (identifierArg == null) {
-                    throw new NullPointerException("identifierArg unexpectedly null.");
-                  }
-                  Number flashModeArg = (Number) args.get(1);
-                  if (flashModeArg == null) {
-                    throw new NullPointerException("flashModeArg unexpectedly null.");
-                  }
                   api.setFlashMode(
                       (identifierArg == null) ? null : identifierArg.longValue(),
                       (flashModeArg == null) ? null : flashModeArg.longValue());
-                  wrapped.put("result", null);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
+                  wrapped.add(0, null);
+                } catch (Throwable exception) {
+                  ArrayList<Object> wrappedError = wrapError(exception);
+                  wrapped = wrappedError;
                 }
                 reply.reply(wrapped);
               });
@@ -1296,32 +1179,24 @@
         if (api != null) {
           channel.setMessageHandler(
               (message, reply) -> {
-                Map<String, Object> wrapped = new HashMap<>();
-                try {
-                  ArrayList<Object> args = (ArrayList<Object>) message;
-                  Number identifierArg = (Number) args.get(0);
-                  if (identifierArg == null) {
-                    throw new NullPointerException("identifierArg unexpectedly null.");
-                  }
-                  Result<String> resultCallback =
-                      new Result<String>() {
-                        public void success(String result) {
-                          wrapped.put("result", result);
-                          reply.reply(wrapped);
-                        }
+                ArrayList<Object> wrapped = new ArrayList<Object>();
+                ArrayList<Object> args = (ArrayList<Object>) message;
+                Number identifierArg = (Number) args.get(0);
+                Result<String> resultCallback =
+                    new Result<String>() {
+                      public void success(String result) {
+                        wrapped.add(0, result);
+                        reply.reply(wrapped);
+                      }
 
-                        public void error(Throwable error) {
-                          wrapped.put("error", wrapError(error));
-                          reply.reply(wrapped);
-                        }
-                      };
+                      public void error(Throwable error) {
+                        ArrayList<Object> wrappedError = wrapError(error);
+                        reply.reply(wrappedError);
+                      }
+                    };
 
-                  api.takePicture(
-                      (identifierArg == null) ? null : identifierArg.longValue(), resultCallback);
-                } catch (Error | RuntimeException exception) {
-                  wrapped.put("error", wrapError(exception));
-                  reply.reply(wrapped);
-                }
+                api.takePicture(
+                    (identifierArg == null) ? null : identifierArg.longValue(), resultCallback);
               });
         } else {
           channel.setMessageHandler(null);
@@ -1329,14 +1204,4 @@
       }
     }
   }
-
-  private static Map<String, Object> wrapError(Throwable exception) {
-    Map<String, Object> errorMap = new HashMap<>();
-    errorMap.put("message", exception.toString());
-    errorMap.put("code", exception.getClass().getSimpleName());
-    errorMap.put(
-        "details",
-        "Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception));
-    return errorMap;
-  }
 }
diff --git a/packages/camera/camera_android_camerax/lib/src/camerax_library.g.dart b/packages/camera/camera_android_camerax/lib/src/camerax_library.g.dart
index 5d1e5b1..473839c 100644
--- a/packages/camera/camera_android_camerax/lib/src/camerax_library.g.dart
+++ b/packages/camera/camera_android_camerax/lib/src/camerax_library.g.dart
@@ -1,13 +1,14 @@
 // Copyright 2013 The Flutter Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
-// Autogenerated from Pigeon (v3.2.9), do not edit directly.
+// Autogenerated from Pigeon (v9.1.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
-import 'dart:async';
-import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List;
 
-import 'package:flutter/foundation.dart' show WriteBuffer, ReadBuffer;
+import 'dart:async';
+import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
+
+import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
 import 'package:flutter/services.dart';
 
 class ResolutionInfo {
@@ -17,20 +18,21 @@
   });
 
   int width;
+
   int height;
 
   Object encode() {
-    final Map<Object?, Object?> pigeonMap = <Object?, Object?>{};
-    pigeonMap['width'] = width;
-    pigeonMap['height'] = height;
-    return pigeonMap;
+    return <Object?>[
+      width,
+      height,
+    ];
   }
 
-  static ResolutionInfo decode(Object message) {
-    final Map<Object?, Object?> pigeonMap = message as Map<Object?, Object?>;
+  static ResolutionInfo decode(Object result) {
+    result as List<Object?>;
     return ResolutionInfo(
-      width: pigeonMap['width']! as int,
-      height: pigeonMap['height']! as int,
+      width: result[0]! as int,
+      height: result[1]! as int,
     );
   }
 }
@@ -42,57 +44,53 @@
   });
 
   String errorCode;
+
   String description;
 
   Object encode() {
-    final Map<Object?, Object?> pigeonMap = <Object?, Object?>{};
-    pigeonMap['errorCode'] = errorCode;
-    pigeonMap['description'] = description;
-    return pigeonMap;
+    return <Object?>[
+      errorCode,
+      description,
+    ];
   }
 
-  static CameraPermissionsErrorData decode(Object message) {
-    final Map<Object?, Object?> pigeonMap = message as Map<Object?, Object?>;
+  static CameraPermissionsErrorData decode(Object result) {
+    result as List<Object?>;
     return CameraPermissionsErrorData(
-      errorCode: pigeonMap['errorCode']! as String,
-      description: pigeonMap['description']! as String,
+      errorCode: result[0]! as String,
+      description: result[1]! as String,
     );
   }
 }
 
-class _InstanceManagerHostApiCodec extends StandardMessageCodec {
-  const _InstanceManagerHostApiCodec();
-}
-
 class InstanceManagerHostApi {
   /// Constructor for [InstanceManagerHostApi].  The [binaryMessenger] named argument is
   /// available for dependency injection.  If it is left null, the default
   /// BinaryMessenger will be used which routes to the host platform.
   InstanceManagerHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
-  static const MessageCodec<Object?> codec = _InstanceManagerHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
+  /// Clear the native `InstanceManager`.
+  ///
+  /// This is typically only used after a hot restart.
   Future<void> clear() async {
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
         'dev.flutter.pigeon.InstanceManagerHostApi.clear', codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap =
-        await channel.send(null) as Map<Object?, Object?>?;
-    if (replyMap == null) {
+    final List<Object?>? replyList = await channel.send(null) as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
     } else {
       return;
@@ -100,39 +98,32 @@
   }
 }
 
-class _JavaObjectHostApiCodec extends StandardMessageCodec {
-  const _JavaObjectHostApiCodec();
-}
-
 class JavaObjectHostApi {
   /// Constructor for [JavaObjectHostApi].  The [binaryMessenger] named argument is
   /// available for dependency injection.  If it is left null, the default
   /// BinaryMessenger will be used which routes to the host platform.
   JavaObjectHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
-  static const MessageCodec<Object?> codec = _JavaObjectHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   Future<void> dispose(int arg_identifier) async {
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
         'dev.flutter.pigeon.JavaObjectHostApi.dispose', codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap =
-        await channel.send(<Object?>[arg_identifier]) as Map<Object?, Object?>?;
-    if (replyMap == null) {
+    final List<Object?>? replyList =
+        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
     } else {
       return;
@@ -140,14 +131,11 @@
   }
 }
 
-class _JavaObjectFlutterApiCodec extends StandardMessageCodec {
-  const _JavaObjectFlutterApiCodec();
-}
-
 abstract class JavaObjectFlutterApi {
-  static const MessageCodec<Object?> codec = _JavaObjectFlutterApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void dispose(int identifier);
+
   static void setup(JavaObjectFlutterApi? api,
       {BinaryMessenger? binaryMessenger}) {
     {
@@ -172,59 +160,49 @@
   }
 }
 
-class _CameraInfoHostApiCodec extends StandardMessageCodec {
-  const _CameraInfoHostApiCodec();
-}
-
 class CameraInfoHostApi {
   /// Constructor for [CameraInfoHostApi].  The [binaryMessenger] named argument is
   /// available for dependency injection.  If it is left null, the default
   /// BinaryMessenger will be used which routes to the host platform.
   CameraInfoHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
-  static const MessageCodec<Object?> codec = _CameraInfoHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   Future<int> getSensorRotationDegrees(int arg_identifier) async {
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
         'dev.flutter.pigeon.CameraInfoHostApi.getSensorRotationDegrees', codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap =
-        await channel.send(<Object?>[arg_identifier]) as Map<Object?, Object?>?;
-    if (replyMap == null) {
+    final List<Object?>? replyList =
+        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
-    } else if (replyMap['result'] == null) {
+    } else if (replyList[0] == null) {
       throw PlatformException(
         code: 'null-error',
         message: 'Host platform returned null value for non-null return value.',
       );
     } else {
-      return (replyMap['result'] as int?)!;
+      return (replyList[0] as int?)!;
     }
   }
 }
 
-class _CameraInfoFlutterApiCodec extends StandardMessageCodec {
-  const _CameraInfoFlutterApiCodec();
-}
-
 abstract class CameraInfoFlutterApi {
-  static const MessageCodec<Object?> codec = _CameraInfoFlutterApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void create(int identifier);
+
   static void setup(CameraInfoFlutterApi? api,
       {BinaryMessenger? binaryMessenger}) {
     {
@@ -249,40 +227,32 @@
   }
 }
 
-class _CameraSelectorHostApiCodec extends StandardMessageCodec {
-  const _CameraSelectorHostApiCodec();
-}
-
 class CameraSelectorHostApi {
   /// Constructor for [CameraSelectorHostApi].  The [binaryMessenger] named argument is
   /// available for dependency injection.  If it is left null, the default
   /// BinaryMessenger will be used which routes to the host platform.
   CameraSelectorHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
-  static const MessageCodec<Object?> codec = _CameraSelectorHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   Future<void> create(int arg_identifier, int? arg_lensFacing) async {
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
         'dev.flutter.pigeon.CameraSelectorHostApi.create', codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap =
-        await channel.send(<Object?>[arg_identifier, arg_lensFacing])
-            as Map<Object?, Object?>?;
-    if (replyMap == null) {
+    final List<Object?>? replyList = await channel
+        .send(<Object?>[arg_identifier, arg_lensFacing]) as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
     } else {
       return;
@@ -294,41 +264,35 @@
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
         'dev.flutter.pigeon.CameraSelectorHostApi.filter', codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap =
-        await channel.send(<Object?>[arg_identifier, arg_cameraInfoIds])
-            as Map<Object?, Object?>?;
-    if (replyMap == null) {
+    final List<Object?>? replyList = await channel
+        .send(<Object?>[arg_identifier, arg_cameraInfoIds]) as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
-    } else if (replyMap['result'] == null) {
+    } else if (replyList[0] == null) {
       throw PlatformException(
         code: 'null-error',
         message: 'Host platform returned null value for non-null return value.',
       );
     } else {
-      return (replyMap['result'] as List<Object?>?)!.cast<int?>();
+      return (replyList[0] as List<Object?>?)!.cast<int?>();
     }
   }
 }
 
-class _CameraSelectorFlutterApiCodec extends StandardMessageCodec {
-  const _CameraSelectorFlutterApiCodec();
-}
-
 abstract class CameraSelectorFlutterApi {
-  static const MessageCodec<Object?> codec = _CameraSelectorFlutterApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void create(int identifier, int? lensFacing);
+
   static void setup(CameraSelectorFlutterApi? api,
       {BinaryMessenger? binaryMessenger}) {
     {
@@ -354,48 +318,39 @@
   }
 }
 
-class _ProcessCameraProviderHostApiCodec extends StandardMessageCodec {
-  const _ProcessCameraProviderHostApiCodec();
-}
-
 class ProcessCameraProviderHostApi {
   /// Constructor for [ProcessCameraProviderHostApi].  The [binaryMessenger] named argument is
   /// available for dependency injection.  If it is left null, the default
   /// BinaryMessenger will be used which routes to the host platform.
   ProcessCameraProviderHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
-  static const MessageCodec<Object?> codec =
-      _ProcessCameraProviderHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   Future<int> getInstance() async {
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
         'dev.flutter.pigeon.ProcessCameraProviderHostApi.getInstance', codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap =
-        await channel.send(null) as Map<Object?, Object?>?;
-    if (replyMap == null) {
+    final List<Object?>? replyList = await channel.send(null) as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
-    } else if (replyMap['result'] == null) {
+    } else if (replyList[0] == null) {
       throw PlatformException(
         code: 'null-error',
         message: 'Host platform returned null value for non-null return value.',
       );
     } else {
-      return (replyMap['result'] as int?)!;
+      return (replyList[0] as int?)!;
     }
   }
 
@@ -404,28 +359,26 @@
         'dev.flutter.pigeon.ProcessCameraProviderHostApi.getAvailableCameraInfos',
         codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap =
-        await channel.send(<Object?>[arg_identifier]) as Map<Object?, Object?>?;
-    if (replyMap == null) {
+    final List<Object?>? replyList =
+        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
-    } else if (replyMap['result'] == null) {
+    } else if (replyList[0] == null) {
       throw PlatformException(
         code: 'null-error',
         message: 'Host platform returned null value for non-null return value.',
       );
     } else {
-      return (replyMap['result'] as List<Object?>?)!.cast<int?>();
+      return (replyList[0] as List<Object?>?)!.cast<int?>();
     }
   }
 
@@ -435,31 +388,29 @@
         'dev.flutter.pigeon.ProcessCameraProviderHostApi.bindToLifecycle',
         codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap = await channel.send(<Object?>[
+    final List<Object?>? replyList = await channel.send(<Object?>[
       arg_identifier,
       arg_cameraSelectorIdentifier,
       arg_useCaseIds
-    ]) as Map<Object?, Object?>?;
-    if (replyMap == null) {
+    ]) as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
-    } else if (replyMap['result'] == null) {
+    } else if (replyList[0] == null) {
       throw PlatformException(
         code: 'null-error',
         message: 'Host platform returned null value for non-null return value.',
       );
     } else {
-      return (replyMap['result'] as int?)!;
+      return (replyList[0] as int?)!;
     }
   }
 
@@ -467,29 +418,27 @@
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
         'dev.flutter.pigeon.ProcessCameraProviderHostApi.isBound', codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap =
+    final List<Object?>? replyList =
         await channel.send(<Object?>[arg_identifier, arg_useCaseIdentifier])
-            as Map<Object?, Object?>?;
-    if (replyMap == null) {
+            as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
-    } else if (replyMap['result'] == null) {
+    } else if (replyList[0] == null) {
       throw PlatformException(
         code: 'null-error',
         message: 'Host platform returned null value for non-null return value.',
       );
     } else {
-      return (replyMap['result'] as bool?)!;
+      return (replyList[0] as bool?)!;
     }
   }
 
@@ -497,21 +446,18 @@
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
         'dev.flutter.pigeon.ProcessCameraProviderHostApi.unbind', codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap =
-        await channel.send(<Object?>[arg_identifier, arg_useCaseIds])
-            as Map<Object?, Object?>?;
-    if (replyMap == null) {
+    final List<Object?>? replyList = await channel
+        .send(<Object?>[arg_identifier, arg_useCaseIds]) as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
     } else {
       return;
@@ -522,20 +468,18 @@
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
         'dev.flutter.pigeon.ProcessCameraProviderHostApi.unbindAll', codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap =
-        await channel.send(<Object?>[arg_identifier]) as Map<Object?, Object?>?;
-    if (replyMap == null) {
+    final List<Object?>? replyList =
+        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
     } else {
       return;
@@ -543,15 +487,11 @@
   }
 }
 
-class _ProcessCameraProviderFlutterApiCodec extends StandardMessageCodec {
-  const _ProcessCameraProviderFlutterApiCodec();
-}
-
 abstract class ProcessCameraProviderFlutterApi {
-  static const MessageCodec<Object?> codec =
-      _ProcessCameraProviderFlutterApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void create(int identifier);
+
   static void setup(ProcessCameraProviderFlutterApi? api,
       {BinaryMessenger? binaryMessenger}) {
     {
@@ -576,14 +516,11 @@
   }
 }
 
-class _CameraFlutterApiCodec extends StandardMessageCodec {
-  const _CameraFlutterApiCodec();
-}
-
 abstract class CameraFlutterApi {
-  static const MessageCodec<Object?> codec = _CameraFlutterApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void create(int identifier);
+
   static void setup(CameraFlutterApi? api, {BinaryMessenger? binaryMessenger}) {
     {
       final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
@@ -624,7 +561,6 @@
     switch (type) {
       case 128:
         return CameraPermissionsErrorData.decode(readValue(buffer)!);
-
       default:
         return super.readValueOfType(type, buffer);
     }
@@ -637,7 +573,6 @@
   /// BinaryMessenger will be used which routes to the host platform.
   SystemServicesHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
   static const MessageCodec<Object?> codec = _SystemServicesHostApiCodec();
@@ -648,23 +583,21 @@
         'dev.flutter.pigeon.SystemServicesHostApi.requestCameraPermissions',
         codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap = await channel
-        .send(<Object?>[arg_enableAudio]) as Map<Object?, Object?>?;
-    if (replyMap == null) {
+    final List<Object?>? replyList =
+        await channel.send(<Object?>[arg_enableAudio]) as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
     } else {
-      return (replyMap['result'] as CameraPermissionsErrorData?);
+      return (replyList[0] as CameraPermissionsErrorData?);
     }
   }
 
@@ -674,21 +607,19 @@
         'dev.flutter.pigeon.SystemServicesHostApi.startListeningForDeviceOrientationChange',
         codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap =
+    final List<Object?>? replyList =
         await channel.send(<Object?>[arg_isFrontFacing, arg_sensorOrientation])
-            as Map<Object?, Object?>?;
-    if (replyMap == null) {
+            as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
     } else {
       return;
@@ -700,20 +631,17 @@
         'dev.flutter.pigeon.SystemServicesHostApi.stopListeningForDeviceOrientationChange',
         codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap =
-        await channel.send(null) as Map<Object?, Object?>?;
-    if (replyMap == null) {
+    final List<Object?>? replyList = await channel.send(null) as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
     } else {
       return;
@@ -721,15 +649,13 @@
   }
 }
 
-class _SystemServicesFlutterApiCodec extends StandardMessageCodec {
-  const _SystemServicesFlutterApiCodec();
-}
-
 abstract class SystemServicesFlutterApi {
-  static const MessageCodec<Object?> codec = _SystemServicesFlutterApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void onDeviceOrientationChanged(String orientation);
+
   void onCameraError(String errorDescription);
+
   static void setup(SystemServicesFlutterApi? api,
       {BinaryMessenger? binaryMessenger}) {
     {
@@ -794,10 +720,8 @@
     switch (type) {
       case 128:
         return ResolutionInfo.decode(readValue(buffer)!);
-
       case 129:
         return ResolutionInfo.decode(readValue(buffer)!);
-
       default:
         return super.readValueOfType(type, buffer);
     }
@@ -810,7 +734,6 @@
   /// BinaryMessenger will be used which routes to the host platform.
   PreviewHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
   static const MessageCodec<Object?> codec = _PreviewHostApiCodec();
@@ -820,21 +743,19 @@
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
         'dev.flutter.pigeon.PreviewHostApi.create', codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap = await channel
+    final List<Object?>? replyList = await channel
             .send(<Object?>[arg_identifier, arg_rotation, arg_targetResolution])
-        as Map<Object?, Object?>?;
-    if (replyMap == null) {
+        as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
     } else {
       return;
@@ -845,28 +766,26 @@
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
         'dev.flutter.pigeon.PreviewHostApi.setSurfaceProvider', codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap =
-        await channel.send(<Object?>[arg_identifier]) as Map<Object?, Object?>?;
-    if (replyMap == null) {
+    final List<Object?>? replyList =
+        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
-    } else if (replyMap['result'] == null) {
+    } else if (replyList[0] == null) {
       throw PlatformException(
         code: 'null-error',
         message: 'Host platform returned null value for non-null return value.',
       );
     } else {
-      return (replyMap['result'] as int?)!;
+      return (replyList[0] as int?)!;
     }
   }
 
@@ -874,20 +793,17 @@
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
         'dev.flutter.pigeon.PreviewHostApi.releaseFlutterSurfaceTexture', codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap =
-        await channel.send(null) as Map<Object?, Object?>?;
-    if (replyMap == null) {
+    final List<Object?>? replyList = await channel.send(null) as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
     } else {
       return;
@@ -898,28 +814,26 @@
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
         'dev.flutter.pigeon.PreviewHostApi.getResolutionInfo', codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap =
-        await channel.send(<Object?>[arg_identifier]) as Map<Object?, Object?>?;
-    if (replyMap == null) {
+    final List<Object?>? replyList =
+        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
-    } else if (replyMap['result'] == null) {
+    } else if (replyList[0] == null) {
       throw PlatformException(
         code: 'null-error',
         message: 'Host platform returned null value for non-null return value.',
       );
     } else {
-      return (replyMap['result'] as ResolutionInfo?)!;
+      return (replyList[0] as ResolutionInfo?)!;
     }
   }
 }
@@ -941,7 +855,6 @@
     switch (type) {
       case 128:
         return ResolutionInfo.decode(readValue(buffer)!);
-
       default:
         return super.readValueOfType(type, buffer);
     }
@@ -954,7 +867,6 @@
   /// BinaryMessenger will be used which routes to the host platform.
   ImageCaptureHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
   static const MessageCodec<Object?> codec = _ImageCaptureHostApiCodec();
@@ -964,21 +876,19 @@
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
         'dev.flutter.pigeon.ImageCaptureHostApi.create', codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap = await channel.send(
+    final List<Object?>? replyList = await channel.send(
             <Object?>[arg_identifier, arg_flashMode, arg_targetResolution])
-        as Map<Object?, Object?>?;
-    if (replyMap == null) {
+        as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
     } else {
       return;
@@ -989,21 +899,18 @@
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
         'dev.flutter.pigeon.ImageCaptureHostApi.setFlashMode', codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap =
-        await channel.send(<Object?>[arg_identifier, arg_flashMode])
-            as Map<Object?, Object?>?;
-    if (replyMap == null) {
+    final List<Object?>? replyList = await channel
+        .send(<Object?>[arg_identifier, arg_flashMode]) as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
     } else {
       return;
@@ -1014,28 +921,26 @@
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
         'dev.flutter.pigeon.ImageCaptureHostApi.takePicture', codec,
         binaryMessenger: _binaryMessenger);
-    final Map<Object?, Object?>? replyMap =
-        await channel.send(<Object?>[arg_identifier]) as Map<Object?, Object?>?;
-    if (replyMap == null) {
+    final List<Object?>? replyList =
+        await channel.send(<Object?>[arg_identifier]) as List<Object?>?;
+    if (replyList == null) {
       throw PlatformException(
         code: 'channel-error',
         message: 'Unable to establish connection on channel.',
       );
-    } else if (replyMap['error'] != null) {
-      final Map<Object?, Object?> error =
-          (replyMap['error'] as Map<Object?, Object?>?)!;
+    } else if (replyList.length > 1) {
       throw PlatformException(
-        code: (error['code'] as String?)!,
-        message: error['message'] as String?,
-        details: error['details'],
+        code: replyList[0]! as String,
+        message: replyList[1] as String?,
+        details: replyList[2],
       );
-    } else if (replyMap['result'] == null) {
+    } else if (replyList[0] == null) {
       throw PlatformException(
         code: 'null-error',
         message: 'Host platform returned null value for non-null return value.',
       );
     } else {
-      return (replyMap['result'] as String?)!;
+      return (replyList[0] as String?)!;
     }
   }
 }
diff --git a/packages/camera/camera_android_camerax/pubspec.yaml b/packages/camera/camera_android_camerax/pubspec.yaml
index 78262b7..764b057 100644
--- a/packages/camera/camera_android_camerax/pubspec.yaml
+++ b/packages/camera/camera_android_camerax/pubspec.yaml
@@ -31,4 +31,4 @@
   flutter_test:
     sdk: flutter
   mockito: 5.3.2
-  pigeon: ^3.2.6
+  pigeon: ^9.1.0
diff --git a/packages/camera/camera_android_camerax/test/test_camerax_library.g.dart b/packages/camera/camera_android_camerax/test/test_camerax_library.g.dart
index e065928..2bb655f 100644
--- a/packages/camera/camera_android_camerax/test/test_camerax_library.g.dart
+++ b/packages/camera/camera_android_camerax/test/test_camerax_library.g.dart
@@ -1,26 +1,26 @@
 // Copyright 2013 The Flutter Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
-// Autogenerated from Pigeon (v3.2.9), do not edit directly.
+// Autogenerated from Pigeon (v9.1.1), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import
 // ignore_for_file: avoid_relative_lib_imports
 import 'dart:async';
-import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List;
-import 'package:flutter/foundation.dart' show WriteBuffer, ReadBuffer;
+import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
+import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
 import 'package:flutter/services.dart';
 import 'package:flutter_test/flutter_test.dart';
 
 import 'package:camera_android_camerax/src/camerax_library.g.dart';
 
-class _TestInstanceManagerHostApiCodec extends StandardMessageCodec {
-  const _TestInstanceManagerHostApiCodec();
-}
-
 abstract class TestInstanceManagerHostApi {
-  static const MessageCodec<Object?> codec = _TestInstanceManagerHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
+  /// Clear the native `InstanceManager`.
+  ///
+  /// This is typically only used after a hot restart.
   void clear();
+
   static void setup(TestInstanceManagerHostApi? api,
       {BinaryMessenger? binaryMessenger}) {
     {
@@ -33,21 +33,18 @@
         channel.setMockMessageHandler((Object? message) async {
           // ignore message
           api.clear();
-          return <Object?, Object?>{};
+          return <Object?>[];
         });
       }
     }
   }
 }
 
-class _TestJavaObjectHostApiCodec extends StandardMessageCodec {
-  const _TestJavaObjectHostApiCodec();
-}
-
 abstract class TestJavaObjectHostApi {
-  static const MessageCodec<Object?> codec = _TestJavaObjectHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void dispose(int identifier);
+
   static void setup(TestJavaObjectHostApi? api,
       {BinaryMessenger? binaryMessenger}) {
     {
@@ -65,21 +62,18 @@
           assert(arg_identifier != null,
               'Argument for dev.flutter.pigeon.JavaObjectHostApi.dispose was null, expected non-null int.');
           api.dispose(arg_identifier!);
-          return <Object?, Object?>{};
+          return <Object?>[];
         });
       }
     }
   }
 }
 
-class _TestCameraInfoHostApiCodec extends StandardMessageCodec {
-  const _TestCameraInfoHostApiCodec();
-}
-
 abstract class TestCameraInfoHostApi {
-  static const MessageCodec<Object?> codec = _TestCameraInfoHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   int getSensorRotationDegrees(int identifier);
+
   static void setup(TestCameraInfoHostApi? api,
       {BinaryMessenger? binaryMessenger}) {
     {
@@ -98,22 +92,20 @@
           assert(arg_identifier != null,
               'Argument for dev.flutter.pigeon.CameraInfoHostApi.getSensorRotationDegrees was null, expected non-null int.');
           final int output = api.getSensorRotationDegrees(arg_identifier!);
-          return <Object?, Object?>{'result': output};
+          return <Object?>[output];
         });
       }
     }
   }
 }
 
-class _TestCameraSelectorHostApiCodec extends StandardMessageCodec {
-  const _TestCameraSelectorHostApiCodec();
-}
-
 abstract class TestCameraSelectorHostApi {
-  static const MessageCodec<Object?> codec = _TestCameraSelectorHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void create(int identifier, int? lensFacing);
+
   List<int?> filter(int identifier, List<int?> cameraInfoIds);
+
   static void setup(TestCameraSelectorHostApi? api,
       {BinaryMessenger? binaryMessenger}) {
     {
@@ -132,7 +124,7 @@
               'Argument for dev.flutter.pigeon.CameraSelectorHostApi.create was null, expected non-null int.');
           final int? arg_lensFacing = (args[1] as int?);
           api.create(arg_identifier!, arg_lensFacing);
-          return <Object?, Object?>{};
+          return <Object?>[];
         });
       }
     }
@@ -156,28 +148,29 @@
               'Argument for dev.flutter.pigeon.CameraSelectorHostApi.filter was null, expected non-null List<int?>.');
           final List<int?> output =
               api.filter(arg_identifier!, arg_cameraInfoIds!);
-          return <Object?, Object?>{'result': output};
+          return <Object?>[output];
         });
       }
     }
   }
 }
 
-class _TestProcessCameraProviderHostApiCodec extends StandardMessageCodec {
-  const _TestProcessCameraProviderHostApiCodec();
-}
-
 abstract class TestProcessCameraProviderHostApi {
-  static const MessageCodec<Object?> codec =
-      _TestProcessCameraProviderHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   Future<int> getInstance();
+
   List<int?> getAvailableCameraInfos(int identifier);
+
   int bindToLifecycle(
       int identifier, int cameraSelectorIdentifier, List<int?> useCaseIds);
+
   bool isBound(int identifier, int useCaseIdentifier);
+
   void unbind(int identifier, List<int?> useCaseIds);
+
   void unbindAll(int identifier);
+
   static void setup(TestProcessCameraProviderHostApi? api,
       {BinaryMessenger? binaryMessenger}) {
     {
@@ -190,7 +183,7 @@
         channel.setMockMessageHandler((Object? message) async {
           // ignore message
           final int output = await api.getInstance();
-          return <Object?, Object?>{'result': output};
+          return <Object?>[output];
         });
       }
     }
@@ -211,7 +204,7 @@
               'Argument for dev.flutter.pigeon.ProcessCameraProviderHostApi.getAvailableCameraInfos was null, expected non-null int.');
           final List<int?> output =
               api.getAvailableCameraInfos(arg_identifier!);
-          return <Object?, Object?>{'result': output};
+          return <Object?>[output];
         });
       }
     }
@@ -239,7 +232,7 @@
               'Argument for dev.flutter.pigeon.ProcessCameraProviderHostApi.bindToLifecycle was null, expected non-null List<int?>.');
           final int output = api.bindToLifecycle(
               arg_identifier!, arg_cameraSelectorIdentifier!, arg_useCaseIds!);
-          return <Object?, Object?>{'result': output};
+          return <Object?>[output];
         });
       }
     }
@@ -262,7 +255,7 @@
               'Argument for dev.flutter.pigeon.ProcessCameraProviderHostApi.isBound was null, expected non-null int.');
           final bool output =
               api.isBound(arg_identifier!, arg_useCaseIdentifier!);
-          return <Object?, Object?>{'result': output};
+          return <Object?>[output];
         });
       }
     }
@@ -285,7 +278,7 @@
           assert(arg_useCaseIds != null,
               'Argument for dev.flutter.pigeon.ProcessCameraProviderHostApi.unbind was null, expected non-null List<int?>.');
           api.unbind(arg_identifier!, arg_useCaseIds!);
-          return <Object?, Object?>{};
+          return <Object?>[];
         });
       }
     }
@@ -304,7 +297,7 @@
           assert(arg_identifier != null,
               'Argument for dev.flutter.pigeon.ProcessCameraProviderHostApi.unbindAll was null, expected non-null int.');
           api.unbindAll(arg_identifier!);
-          return <Object?, Object?>{};
+          return <Object?>[];
         });
       }
     }
@@ -328,7 +321,6 @@
     switch (type) {
       case 128:
         return CameraPermissionsErrorData.decode(readValue(buffer)!);
-
       default:
         return super.readValueOfType(type, buffer);
     }
@@ -340,9 +332,12 @@
 
   Future<CameraPermissionsErrorData?> requestCameraPermissions(
       bool enableAudio);
+
   void startListeningForDeviceOrientationChange(
       bool isFrontFacing, int sensorOrientation);
+
   void stopListeningForDeviceOrientationChange();
+
   static void setup(TestSystemServicesHostApi? api,
       {BinaryMessenger? binaryMessenger}) {
     {
@@ -362,7 +357,7 @@
               'Argument for dev.flutter.pigeon.SystemServicesHostApi.requestCameraPermissions was null, expected non-null bool.');
           final CameraPermissionsErrorData? output =
               await api.requestCameraPermissions(arg_enableAudio!);
-          return <Object?, Object?>{'result': output};
+          return <Object?>[output];
         });
       }
     }
@@ -386,7 +381,7 @@
               'Argument for dev.flutter.pigeon.SystemServicesHostApi.startListeningForDeviceOrientationChange was null, expected non-null int.');
           api.startListeningForDeviceOrientationChange(
               arg_isFrontFacing!, arg_sensorOrientation!);
-          return <Object?, Object?>{};
+          return <Object?>[];
         });
       }
     }
@@ -401,7 +396,7 @@
         channel.setMockMessageHandler((Object? message) async {
           // ignore message
           api.stopListeningForDeviceOrientationChange();
-          return <Object?, Object?>{};
+          return <Object?>[];
         });
       }
     }
@@ -428,10 +423,8 @@
     switch (type) {
       case 128:
         return ResolutionInfo.decode(readValue(buffer)!);
-
       case 129:
         return ResolutionInfo.decode(readValue(buffer)!);
-
       default:
         return super.readValueOfType(type, buffer);
     }
@@ -442,9 +435,13 @@
   static const MessageCodec<Object?> codec = _TestPreviewHostApiCodec();
 
   void create(int identifier, int? rotation, ResolutionInfo? targetResolution);
+
   int setSurfaceProvider(int identifier);
+
   void releaseFlutterSurfaceTexture();
+
   ResolutionInfo getResolutionInfo(int identifier);
+
   static void setup(TestPreviewHostApi? api,
       {BinaryMessenger? binaryMessenger}) {
     {
@@ -465,7 +462,7 @@
           final ResolutionInfo? arg_targetResolution =
               (args[2] as ResolutionInfo?);
           api.create(arg_identifier!, arg_rotation, arg_targetResolution);
-          return <Object?, Object?>{};
+          return <Object?>[];
         });
       }
     }
@@ -484,7 +481,7 @@
           assert(arg_identifier != null,
               'Argument for dev.flutter.pigeon.PreviewHostApi.setSurfaceProvider was null, expected non-null int.');
           final int output = api.setSurfaceProvider(arg_identifier!);
-          return <Object?, Object?>{'result': output};
+          return <Object?>[output];
         });
       }
     }
@@ -499,7 +496,7 @@
         channel.setMockMessageHandler((Object? message) async {
           // ignore message
           api.releaseFlutterSurfaceTexture();
-          return <Object?, Object?>{};
+          return <Object?>[];
         });
       }
     }
@@ -518,7 +515,7 @@
           assert(arg_identifier != null,
               'Argument for dev.flutter.pigeon.PreviewHostApi.getResolutionInfo was null, expected non-null int.');
           final ResolutionInfo output = api.getResolutionInfo(arg_identifier!);
-          return <Object?, Object?>{'result': output};
+          return <Object?>[output];
         });
       }
     }
@@ -542,7 +539,6 @@
     switch (type) {
       case 128:
         return ResolutionInfo.decode(readValue(buffer)!);
-
       default:
         return super.readValueOfType(type, buffer);
     }
@@ -553,8 +549,11 @@
   static const MessageCodec<Object?> codec = _TestImageCaptureHostApiCodec();
 
   void create(int identifier, int? flashMode, ResolutionInfo? targetResolution);
+
   void setFlashMode(int identifier, int flashMode);
+
   Future<String> takePicture(int identifier);
+
   static void setup(TestImageCaptureHostApi? api,
       {BinaryMessenger? binaryMessenger}) {
     {
@@ -575,7 +574,7 @@
           final ResolutionInfo? arg_targetResolution =
               (args[2] as ResolutionInfo?);
           api.create(arg_identifier!, arg_flashMode, arg_targetResolution);
-          return <Object?, Object?>{};
+          return <Object?>[];
         });
       }
     }
@@ -597,7 +596,7 @@
           assert(arg_flashMode != null,
               'Argument for dev.flutter.pigeon.ImageCaptureHostApi.setFlashMode was null, expected non-null int.');
           api.setFlashMode(arg_identifier!, arg_flashMode!);
-          return <Object?, Object?>{};
+          return <Object?>[];
         });
       }
     }
@@ -616,7 +615,7 @@
           assert(arg_identifier != null,
               'Argument for dev.flutter.pigeon.ImageCaptureHostApi.takePicture was null, expected non-null int.');
           final String output = await api.takePicture(arg_identifier!);
-          return <Object?, Object?>{'result': output};
+          return <Object?>[output];
         });
       }
     }
