[google_maps_flutter] Updates platform interface to new analysis options (#5793)

diff --git a/analysis_options.yaml b/analysis_options.yaml
index 87f7d6f..87515a4 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -2,10 +2,6 @@
 # with minimal changes for this repository. The goal is to move toward using a
 # shared set of analysis options as much as possible, and eventually a shared
 # file.
-#
-# Plugins that have not yet switched from the previous set of options have a
-# local analysis_options.yaml that points to analysis_options_legacy.yaml
-# instead.
 
 # Specify analysis options.
 #
diff --git a/analysis_options_legacy.yaml b/analysis_options_legacy.yaml
deleted file mode 100644
index da3c180..0000000
--- a/analysis_options_legacy.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-include: package:pedantic/analysis_options.1.8.0.yaml
-analyzer:
-  exclude:
-    # Ignore generated files
-    - '**/*.g.dart'
-    - 'lib/src/generated/*.dart'
-    - '**/*.mocks.dart' # Mockito @GenerateMocks
-    - '**/*.pigeon.dart' # Pigeon generated file
-  errors:
-    always_require_non_null_named_parameters: false # not needed with nnbd
-    unnecessary_null_comparison: false # Turned as long as nnbd mix-mode is supported.
-linter:
-  rules:
-    - public_member_api_docs
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md
index b6e15d2..0359bab 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md
@@ -1,5 +1,6 @@
-## NEXT
+## 2.1.7
 
+* Updates code for stricter analysis options.
 * Removes unnecessary imports.
 
 ## 2.1.6
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/analysis_options.yaml b/packages/google_maps_flutter/google_maps_flutter_platform_interface/analysis_options.yaml
deleted file mode 100644
index 5aeb4e7..0000000
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/analysis_options.yaml
+++ /dev/null
@@ -1 +0,0 @@
-include: ../../../analysis_options_legacy.yaml
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/google_maps_flutter_platform_interface.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/google_maps_flutter_platform_interface.dart
index 3007000..b83eaf4 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/google_maps_flutter_platform_interface.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/google_maps_flutter_platform_interface.dart
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+export 'src/events/map_event.dart';
 export 'src/method_channel/method_channel_google_maps_flutter.dart'
     show MethodChannelGoogleMapsFlutter;
 export 'src/platform_interface/google_maps_flutter_platform.dart';
 export 'src/types/types.dart';
-export 'src/events/map_event.dart';
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/events/map_event.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/events/map_event.dart
index bb41246..8759126 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/events/map_event.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/events/map_event.dart
@@ -34,29 +34,29 @@
 /// events to access the `.position` property, rather than the more generic `.value`
 /// yielded from the latter.
 class MapEvent<T> {
-  /// The ID of the Map this event is associated to.
-  final int mapId;
-
-  /// The value wrapped by this event
-  final T value;
-
   /// Build a Map Event, that relates a mapId with a given value.
   ///
   /// The `mapId` is the id of the map that triggered the event.
   /// `value` may be `null` in events that don't transport any meaningful data.
   MapEvent(this.mapId, this.value);
+
+  /// The ID of the Map this event is associated to.
+  final int mapId;
+
+  /// The value wrapped by this event
+  final T value;
 }
 
 /// A `MapEvent` associated to a `position`.
 class _PositionedMapEvent<T> extends MapEvent<T> {
-  /// The position where this event happened.
-  final LatLng position;
-
   /// Build a Positioned MapEvent, that relates a mapId and a position with a value.
   ///
   /// The `mapId` is the id of the map that triggered the event.
   /// `value` may be `null` in events that don't transport any meaningful data.
   _PositionedMapEvent(int mapId, this.position, T value) : super(mapId, value);
+
+  /// The position where this event happened.
+  final LatLng position;
 }
 
 // The following events are the ones exposed to the end user. They are semantic extensions
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart
index 9c5cbf5..365da75 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart
@@ -27,11 +27,12 @@
   /// Message describing the assertion error.
   final Object? message;
 
+  @override
   String toString() {
     if (message != null) {
-      return "Unknown map ID $mapId: ${Error.safeToString(message)}";
+      return 'Unknown map ID $mapId: ${Error.safeToString(message)}';
     }
-    return "Unknown map ID $mapId";
+    return 'Unknown map ID $mapId';
   }
 }
 
@@ -48,11 +49,11 @@
 class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform {
   // Keep a collection of id -> channel
   // Every method call passes the int mapId
-  final Map<int, MethodChannel> _channels = {};
+  final Map<int, MethodChannel> _channels = <int, MethodChannel>{};
 
   /// Accesses the MethodChannel associated to the passed mapId.
   MethodChannel channel(int mapId) {
-    MethodChannel? channel = _channels[mapId];
+    final MethodChannel? channel = _channels[mapId];
     if (channel == null) {
       throw UnknownMapIDError(mapId);
     }
@@ -60,7 +61,8 @@
   }
 
   // Keep a collection of mapId to a map of TileOverlays.
-  final Map<int, Map<TileOverlayId, TileOverlay>> _tileOverlays = {};
+  final Map<int, Map<TileOverlayId, TileOverlay>> _tileOverlays =
+      <int, Map<TileOverlayId, TileOverlay>>{};
 
   /// Returns the channel for [mapId], creating it if it doesn't already exist.
   @visibleForTesting
@@ -77,7 +79,7 @@
 
   @override
   Future<void> init(int mapId) {
-    MethodChannel channel = ensureChannelInitialized(mapId);
+    final MethodChannel channel = ensureChannelInitialized(mapId);
     return channel.invokeMethod<void>('map#waitForMap');
   }
 
@@ -91,12 +93,13 @@
   //
   // It is a `broadcast` because multiple controllers will connect to
   // different stream views of this Controller.
-  final StreamController<MapEvent> _mapEventStreamController =
-      StreamController<MapEvent>.broadcast();
+  final StreamController<MapEvent<Object?>> _mapEventStreamController =
+      StreamController<MapEvent<Object?>>.broadcast();
 
   // Returns a filtered view of the events in the _controller, by mapId.
-  Stream<MapEvent> _events(int mapId) =>
-      _mapEventStreamController.stream.where((event) => event.mapId == mapId);
+  Stream<MapEvent<Object?>> _events(int mapId) =>
+      _mapEventStreamController.stream
+          .where((MapEvent<Object?> event) => event.mapId == mapId);
 
   @override
   Stream<CameraMoveStartedEvent> onCameraMoveStarted({required int mapId}) {
@@ -180,52 +183,52 @@
       case 'marker#onTap':
         _mapEventStreamController.add(MarkerTapEvent(
           mapId,
-          MarkerId(call.arguments['markerId']),
+          MarkerId(call.arguments['markerId'] as String),
         ));
         break;
       case 'marker#onDragStart':
         _mapEventStreamController.add(MarkerDragStartEvent(
           mapId,
           LatLng.fromJson(call.arguments['position'])!,
-          MarkerId(call.arguments['markerId']),
+          MarkerId(call.arguments['markerId'] as String),
         ));
         break;
       case 'marker#onDrag':
         _mapEventStreamController.add(MarkerDragEvent(
           mapId,
           LatLng.fromJson(call.arguments['position'])!,
-          MarkerId(call.arguments['markerId']),
+          MarkerId(call.arguments['markerId'] as String),
         ));
         break;
       case 'marker#onDragEnd':
         _mapEventStreamController.add(MarkerDragEndEvent(
           mapId,
           LatLng.fromJson(call.arguments['position'])!,
-          MarkerId(call.arguments['markerId']),
+          MarkerId(call.arguments['markerId'] as String),
         ));
         break;
       case 'infoWindow#onTap':
         _mapEventStreamController.add(InfoWindowTapEvent(
           mapId,
-          MarkerId(call.arguments['markerId']),
+          MarkerId(call.arguments['markerId'] as String),
         ));
         break;
       case 'polyline#onTap':
         _mapEventStreamController.add(PolylineTapEvent(
           mapId,
-          PolylineId(call.arguments['polylineId']),
+          PolylineId(call.arguments['polylineId'] as String),
         ));
         break;
       case 'polygon#onTap':
         _mapEventStreamController.add(PolygonTapEvent(
           mapId,
-          PolygonId(call.arguments['polygonId']),
+          PolygonId(call.arguments['polygonId'] as String),
         ));
         break;
       case 'circle#onTap':
         _mapEventStreamController.add(CircleTapEvent(
           mapId,
-          CircleId(call.arguments['circleId']),
+          CircleId(call.arguments['circleId'] as String),
         ));
         break;
       case 'map#onTap':
@@ -243,17 +246,17 @@
       case 'tileOverlay#getTile':
         final Map<TileOverlayId, TileOverlay>? tileOverlaysForThisMap =
             _tileOverlays[mapId];
-        final String tileOverlayId = call.arguments['tileOverlayId'];
+        final String tileOverlayId = call.arguments['tileOverlayId'] as String;
         final TileOverlay? tileOverlay =
             tileOverlaysForThisMap?[TileOverlayId(tileOverlayId)];
-        TileProvider? tileProvider = tileOverlay?.tileProvider;
+        final TileProvider? tileProvider = tileOverlay?.tileProvider;
         if (tileProvider == null) {
           return TileProvider.noTile.toJson();
         }
         final Tile tile = await tileProvider.getTile(
-          call.arguments['x'],
-          call.arguments['y'],
-          call.arguments['zoom'],
+          call.arguments['x'] as int,
+          call.arguments['y'] as int,
+          call.arguments['zoom'] as int?,
         );
         return tile.toJson();
       default:
@@ -330,7 +333,7 @@
   }) {
     final Map<TileOverlayId, TileOverlay>? currentTileOverlays =
         _tileOverlays[mapId];
-    Set<TileOverlay> previousSet = currentTileOverlays != null
+    final Set<TileOverlay> previousSet = currentTileOverlays != null
         ? currentTileOverlays.values.toSet()
         : <TileOverlay>{};
     final TileOverlayUpdates updates =
@@ -380,9 +383,9 @@
   }) async {
     final List<dynamic> successAndError = (await channel(mapId)
         .invokeMethod<List<dynamic>>('map#setStyle', mapStyle))!;
-    final bool success = successAndError[0];
+    final bool success = successAndError[0] as bool;
     if (!success) {
-      throw MapStyleException(successAndError[1]);
+      throw MapStyleException(successAndError[1] as String);
     }
   }
 
@@ -418,7 +421,7 @@
     final List<dynamic> latLng = (await channel(mapId)
         .invokeMethod<List<dynamic>>(
             'map#getLatLng', screenCoordinate.toJson()))!;
-    return LatLng(latLng[0], latLng[1]);
+    return LatLng(latLng[0] as double, latLng[1] as double);
   }
 
   @override
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart
index b6c7b8b..6386ed2 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart
@@ -5,12 +5,11 @@
 import 'dart:async';
 import 'dart:typed_data';
 
-import 'package:flutter/widgets.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter/material.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/gestures.dart';
-
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter/widgets.dart';
 import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
 import 'package:plugin_platform_interface/plugin_platform_interface.dart';
 
@@ -359,8 +358,8 @@
     Set<TileOverlay> tileOverlays = const <TileOverlay>{},
     Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers =
         const <Factory<OneSequenceGestureRecognizer>>{},
-    // TODO: Replace with a structured type that's part of the interface.
-    // See https://github.com/flutter/flutter/issues/70330.
+    // TODO(stuartmorgan): Replace with a structured type that's part of the
+    // interface. See https://github.com/flutter/flutter/issues/70330.
     Map<String, dynamic> mapOptions = const <String, dynamic>{},
   }) {
     throw UnimplementedError('buildView() has not been implemented.');
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart
index d3dc37e..c43baf4 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart
@@ -6,24 +6,70 @@
 import 'dart:typed_data' show Uint8List;
 import 'dart:ui' show Size;
 
+import 'package:flutter/foundation.dart' show kIsWeb;
 import 'package:flutter/material.dart'
     show ImageConfiguration, AssetImage, AssetBundleImageKey;
 import 'package:flutter/services.dart' show AssetBundle;
 
-import 'package:flutter/foundation.dart' show kIsWeb;
-
 /// Defines a bitmap image. For a marker, this class can be used to set the
 /// image of the marker icon. For a ground overlay, it can be used to set the
 /// image to place on the surface of the earth.
 class BitmapDescriptor {
   const BitmapDescriptor._(this._json);
 
+  /// The inverse of .toJson.
+  // This is needed in Web to re-hydrate BitmapDescriptors that have been
+  // transformed to JSON for transport.
+  // TODO(stuartmorgan): Clean this up. See
+  // https://github.com/flutter/flutter/issues/70330
+  BitmapDescriptor.fromJson(Object json) : _json = json {
+    assert(_json is List<dynamic>);
+    final List<dynamic> jsonList = json as List<dynamic>;
+    assert(_validTypes.contains(jsonList[0]));
+    switch (jsonList[0]) {
+      case _defaultMarker:
+        assert(jsonList.length <= 2);
+        if (jsonList.length == 2) {
+          assert(jsonList[1] is num);
+          final num secondElement = jsonList[1] as num;
+          assert(0 <= secondElement && secondElement < 360);
+        }
+        break;
+      case _fromBytes:
+        assert(jsonList.length == 2);
+        assert(jsonList[1] != null && jsonList[1] is List<int>);
+        assert((jsonList[1] as List<int>).isNotEmpty);
+        break;
+      case _fromAsset:
+        assert(jsonList.length <= 3);
+        assert(jsonList[1] != null && jsonList[1] is String);
+        assert((jsonList[1] as String).isNotEmpty);
+        if (jsonList.length == 3) {
+          assert(jsonList[2] != null && jsonList[2] is String);
+          assert((jsonList[2] as String).isNotEmpty);
+        }
+        break;
+      case _fromAssetImage:
+        assert(jsonList.length <= 4);
+        assert(jsonList[1] != null && jsonList[1] is String);
+        assert((jsonList[1] as String).isNotEmpty);
+        assert(jsonList[2] != null && jsonList[2] is double);
+        if (jsonList.length == 4) {
+          assert(jsonList[3] != null && jsonList[3] is List<dynamic>);
+          assert((jsonList[3] as List<dynamic>).length == 2);
+        }
+        break;
+      default:
+        break;
+    }
+  }
+
   static const String _defaultMarker = 'defaultMarker';
   static const String _fromAsset = 'fromAsset';
   static const String _fromAssetImage = 'fromAssetImage';
   static const String _fromBytes = 'fromBytes';
 
-  static const Set<String> _validTypes = {
+  static const Set<String> _validTypes = <String>{
     _defaultMarker,
     _fromAsset,
     _fromAssetImage,
@@ -86,7 +132,7 @@
     String? package,
     bool mipmaps = true,
   }) async {
-    double? devicePixelRatio = configuration.devicePixelRatio;
+    final double? devicePixelRatio = configuration.devicePixelRatio;
     if (!mipmaps && devicePixelRatio != null) {
       return BitmapDescriptor._(<Object>[
         _fromAssetImage,
@@ -104,7 +150,7 @@
       assetBundleImageKey.name,
       assetBundleImageKey.scale,
       if (kIsWeb && size != null)
-        [
+        <Object>[
           size.width,
           size.height,
         ],
@@ -117,51 +163,6 @@
     return BitmapDescriptor._(<Object>[_fromBytes, byteData]);
   }
 
-  /// The inverse of .toJson.
-  // This is needed in Web to re-hydrate BitmapDescriptors that have been
-  // transformed to JSON for transport.
-  // TODO(https://github.com/flutter/flutter/issues/70330): Clean this up.
-  BitmapDescriptor.fromJson(Object json) : _json = json {
-    assert(_json is List<dynamic>);
-    final jsonList = json as List<dynamic>;
-    assert(_validTypes.contains(jsonList[0]));
-    switch (jsonList[0]) {
-      case _defaultMarker:
-        assert(jsonList.length <= 2);
-        if (jsonList.length == 2) {
-          assert(jsonList[1] is num);
-          assert(0 <= jsonList[1] && jsonList[1] < 360);
-        }
-        break;
-      case _fromBytes:
-        assert(jsonList.length == 2);
-        assert(jsonList[1] != null && jsonList[1] is List<int>);
-        assert((jsonList[1] as List).isNotEmpty);
-        break;
-      case _fromAsset:
-        assert(jsonList.length <= 3);
-        assert(jsonList[1] != null && jsonList[1] is String);
-        assert((jsonList[1] as String).isNotEmpty);
-        if (jsonList.length == 3) {
-          assert(jsonList[2] != null && jsonList[2] is String);
-          assert((jsonList[2] as String).isNotEmpty);
-        }
-        break;
-      case _fromAssetImage:
-        assert(jsonList.length <= 4);
-        assert(jsonList[1] != null && jsonList[1] is String);
-        assert((jsonList[1] as String).isNotEmpty);
-        assert(jsonList[2] != null && jsonList[2] is double);
-        if (jsonList.length == 4) {
-          assert(jsonList[3] != null && jsonList[3] is List);
-          assert((jsonList[3] as List).length == 2);
-        }
-        break;
-      default:
-        break;
-    }
-  }
-
   final Object _json;
 
   /// Convert the object to a Json format.
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/callbacks.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/callbacks.dart
index 3b484c1..5d6af90 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/callbacks.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/callbacks.dart
@@ -10,10 +10,10 @@
 /// registers a camera movement.
 ///
 /// This is used in [GoogleMap.onCameraMove].
-typedef void CameraPositionCallback(CameraPosition position);
+typedef CameraPositionCallback = void Function(CameraPosition position);
 
 /// Callback function taking a single argument.
-typedef void ArgumentCallback<T>(T argument);
+typedef ArgumentCallback<T> = void Function(T argument);
 
 /// Mutable collection of [ArgumentCallback] instances, itself an [ArgumentCallback].
 ///
@@ -35,7 +35,7 @@
     if (length == 1) {
       _callbacks[0].call(argument);
     } else if (0 < length) {
-      for (ArgumentCallback<T> callback
+      for (final ArgumentCallback<T> callback
           in List<ArgumentCallback<T>>.from(_callbacks)) {
         callback(argument);
       }
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart
index 89006eb..6d1ce16 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart
@@ -4,12 +4,15 @@
 
 import 'dart:ui' show Offset;
 
+import 'package:flutter/foundation.dart';
+
 import 'types.dart';
 
 /// The position of the map "camera", the view point from which the world is shown in the map view.
 ///
 /// Aggregates the camera's [target] geographical location, its [zoom] level,
 /// [tilt] angle, and [bearing].
+@immutable
 class CameraPosition {
   /// Creates a immutable representation of the [GoogleMap] camera.
   ///
@@ -72,7 +75,7 @@
   ///
   /// Mainly for internal use.
   static CameraPosition? fromMap(Object? json) {
-    if (json == null || !(json is Map<dynamic, dynamic>)) {
+    if (json == null || json is! Map<dynamic, dynamic>) {
       return null;
     }
     final LatLng? target = LatLng.fromJson(json['target']);
@@ -80,22 +83,26 @@
       return null;
     }
     return CameraPosition(
-      bearing: json['bearing'],
+      bearing: json['bearing'] as double,
       target: target,
-      tilt: json['tilt'],
-      zoom: json['zoom'],
+      tilt: json['tilt'] as double,
+      zoom: json['zoom'] as double,
     );
   }
 
   @override
   bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (runtimeType != other.runtimeType) return false;
-    final CameraPosition typedOther = other as CameraPosition;
-    return bearing == typedOther.bearing &&
-        target == typedOther.target &&
-        tilt == typedOther.tilt &&
-        zoom == typedOther.zoom;
+    if (identical(this, other)) {
+      return true;
+    }
+    if (runtimeType != other.runtimeType) {
+      return false;
+    }
+    return other is CameraPosition &&
+        bearing == other.bearing &&
+        target == other.target &&
+        tilt == other.tilt &&
+        zoom == other.zoom;
   }
 
   @override
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart
index 1e9b218..d9e4b2d 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart
@@ -3,8 +3,8 @@
 // found in the LICENSE file.
 
 import 'package:flutter/foundation.dart' show VoidCallback;
-import 'package:flutter/material.dart' show Color, Colors;
 import 'package:flutter/foundation.dart' show immutable;
+import 'package:flutter/material.dart' show Color, Colors;
 
 import 'types.dart';
 
@@ -105,9 +105,11 @@
   }
 
   /// Creates a new [Circle] object whose values are the same as this instance.
+  @override
   Circle clone() => copyWith();
 
   /// Converts this object to something serializable in JSON.
+  @override
   Object toJson() {
     final Map<String, Object> json = <String, Object>{};
 
@@ -132,18 +134,22 @@
 
   @override
   bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final Circle typedOther = other as Circle;
-    return circleId == typedOther.circleId &&
-        consumeTapEvents == typedOther.consumeTapEvents &&
-        fillColor == typedOther.fillColor &&
-        center == typedOther.center &&
-        radius == typedOther.radius &&
-        strokeColor == typedOther.strokeColor &&
-        strokeWidth == typedOther.strokeWidth &&
-        visible == typedOther.visible &&
-        zIndex == typedOther.zIndex;
+    if (identical(this, other)) {
+      return true;
+    }
+    if (other.runtimeType != runtimeType) {
+      return false;
+    }
+    return other is Circle &&
+        circleId == other.circleId &&
+        consumeTapEvents == other.consumeTapEvents &&
+        fillColor == other.fillColor &&
+        center == other.center &&
+        radius == other.radius &&
+        strokeColor == other.strokeColor &&
+        strokeWidth == other.strokeWidth &&
+        visible == other.visible &&
+        zIndex == other.zIndex;
   }
 
   @override
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/location.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/location.dart
index 5bc4ca6..81fe08b 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/location.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/location.dart
@@ -2,9 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'package:flutter/foundation.dart' show visibleForTesting;
+import 'package:flutter/foundation.dart'
+    show immutable, objectRuntimeType, visibleForTesting;
 
 /// A pair of latitude and longitude coordinates, stored as degrees.
+@immutable
 class LatLng {
   /// Creates a geographical location specified in degrees [latitude] and
   /// [longitude].
@@ -17,7 +19,7 @@
       : assert(latitude != null),
         assert(longitude != null),
         latitude =
-            (latitude < -90.0 ? -90.0 : (90.0 < latitude ? 90.0 : latitude)),
+            latitude < -90.0 ? -90.0 : (90.0 < latitude ? 90.0 : latitude),
         // Avoids normalization if possible to prevent unnecessary loss of precision
         longitude = longitude >= -180 && longitude < 180
             ? longitude
@@ -40,16 +42,19 @@
       return null;
     }
     assert(json is List && json.length == 2);
-    final list = json as List;
-    return LatLng(list[0], list[1]);
+    final List<Object?> list = json as List<Object?>;
+    return LatLng(list[0]! as double, list[1]! as double);
   }
 
   @override
-  String toString() => '$runtimeType($latitude, $longitude)';
+  String toString() =>
+      '${objectRuntimeType(this, 'LatLng')}($latitude, $longitude)';
 
   @override
-  bool operator ==(Object o) {
-    return o is LatLng && o.latitude == latitude && o.longitude == longitude;
+  bool operator ==(Object other) {
+    return other is LatLng &&
+        other.latitude == latitude &&
+        other.longitude == longitude;
   }
 
   @override
@@ -64,6 +69,7 @@
 ///   if `southwest.longitude` ≤ `northeast.longitude`,
 /// * lng ∈ [-180, `northeast.longitude`] ∪ [`southwest.longitude`, 180],
 ///   if `northeast.longitude` < `southwest.longitude`
+@immutable
 class LatLngBounds {
   /// Creates geographical bounding box with the specified corners.
   ///
@@ -110,7 +116,7 @@
       return null;
     }
     assert(json is List && json.length == 2);
-    final list = json as List;
+    final List<Object?> list = json as List<Object?>;
     return LatLngBounds(
       southwest: LatLng.fromJson(list[0])!,
       northeast: LatLng.fromJson(list[1])!,
@@ -119,14 +125,14 @@
 
   @override
   String toString() {
-    return '$runtimeType($southwest, $northeast)';
+    return '${objectRuntimeType(this, 'LatLngBounds')}($southwest, $northeast)';
   }
 
   @override
-  bool operator ==(Object o) {
-    return o is LatLngBounds &&
-        o.southwest == southwest &&
-        o.northeast == northeast;
+  bool operator ==(Object other) {
+    return other is LatLngBounds &&
+        other.southwest == southwest &&
+        other.northeast == northeast;
   }
 
   @override
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart
index be629e1..953746d 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart
@@ -20,10 +20,13 @@
 
   @override
   bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final MapsObjectId<T> typedOther = other as MapsObjectId<T>;
-    return value == typedOther.value;
+    if (identical(this, other)) {
+      return true;
+    }
+    if (other.runtimeType != runtimeType) {
+      return false;
+    }
+    return other is MapsObjectId<T> && value == other.value;
   }
 
   @override
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object_updates.dart
index 3267cad..0051afc 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object_updates.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object_updates.dart
@@ -2,13 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'package:flutter/foundation.dart' show objectRuntimeType, setEquals;
+import 'package:flutter/foundation.dart'
+    show immutable, objectRuntimeType, setEquals;
 
 import 'maps_object.dart';
 import 'utils/maps_object.dart';
 
 /// Update specification for a set of objects.
-class MapsObjectUpdates<T extends MapsObject> {
+@immutable
+class MapsObjectUpdates<T extends MapsObject<T>> {
   /// Computes updates given previous and current object sets.
   ///
   /// [objectName] is the prefix to use when serializing the updates into a JSON
@@ -43,7 +45,7 @@
     // Returns `true` if [current] is not equals to previous one with the
     // same id.
     bool hasChanged(T current) {
-      final T? previous = previousObjects[current.mapsId as MapsObjectId<T>];
+      final T? previous = previousObjects[current.mapsId];
       return current != previous;
     }
 
@@ -62,21 +64,21 @@
     return _objectsToAdd;
   }
 
-  late Set<T> _objectsToAdd;
+  late final Set<T> _objectsToAdd;
 
   /// Set of objects to be removed in this update.
   Set<MapsObjectId<T>> get objectIdsToRemove {
     return _objectIdsToRemove;
   }
 
-  late Set<MapsObjectId<T>> _objectIdsToRemove;
+  late final Set<MapsObjectId<T>> _objectIdsToRemove;
 
   /// Set of objects to be changed in this update.
   Set<T> get objectsToChange {
     return _objectsToChange;
   }
 
-  late Set<T> _objectsToChange;
+  late final Set<T> _objectsToChange;
 
   /// Converts this object to JSON.
   Object toJson() {
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart
index 8057d29..914e77a 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart
@@ -14,6 +14,7 @@
 }
 
 /// Text labels for a [Marker] info window.
+@immutable
 class InfoWindow {
   /// Creates an immutable representation of a label on for [Marker].
   const InfoWindow({
@@ -81,12 +82,16 @@
 
   @override
   bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final InfoWindow typedOther = other as InfoWindow;
-    return title == typedOther.title &&
-        snippet == typedOther.snippet &&
-        anchor == typedOther.anchor;
+    if (identical(this, other)) {
+      return true;
+    }
+    if (other.runtimeType != runtimeType) {
+      return false;
+    }
+    return other is InfoWindow &&
+        title == other.title &&
+        snippet == other.snippet &&
+        anchor == other.anchor;
   }
 
   @override
@@ -113,7 +118,7 @@
 /// the map's surface; that is, it will not necessarily change orientation
 /// due to map rotations, tilting, or zooming.
 @immutable
-class Marker implements MapsObject {
+class Marker implements MapsObject<Marker> {
   /// Creates a set of marker configuration options.
   ///
   /// Default marker options.
@@ -258,9 +263,11 @@
   }
 
   /// Creates a new [Marker] object whose values are the same as this instance.
+  @override
   Marker clone() => copyWith();
 
   /// Converts this object to something serializable in JSON.
+  @override
   Object toJson() {
     final Map<String, Object> json = <String, Object>{};
 
@@ -287,21 +294,25 @@
 
   @override
   bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final Marker typedOther = other as Marker;
-    return markerId == typedOther.markerId &&
-        alpha == typedOther.alpha &&
-        anchor == typedOther.anchor &&
-        consumeTapEvents == typedOther.consumeTapEvents &&
-        draggable == typedOther.draggable &&
-        flat == typedOther.flat &&
-        icon == typedOther.icon &&
-        infoWindow == typedOther.infoWindow &&
-        position == typedOther.position &&
-        rotation == typedOther.rotation &&
-        visible == typedOther.visible &&
-        zIndex == typedOther.zIndex;
+    if (identical(this, other)) {
+      return true;
+    }
+    if (other.runtimeType != runtimeType) {
+      return false;
+    }
+    return other is Marker &&
+        markerId == other.markerId &&
+        alpha == other.alpha &&
+        anchor == other.anchor &&
+        consumeTapEvents == other.consumeTapEvents &&
+        draggable == other.draggable &&
+        flat == other.flat &&
+        icon == other.icon &&
+        infoWindow == other.infoWindow &&
+        position == other.position &&
+        rotation == other.rotation &&
+        visible == other.visible &&
+        zIndex == other.zIndex;
   }
 
   @override
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart
index 7b6f248..8653ba0 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart
@@ -20,7 +20,7 @@
 
 /// Draws a polygon through geographical locations on the map.
 @immutable
-class Polygon implements MapsObject {
+class Polygon implements MapsObject<Polygon> {
   /// Creates an immutable representation of a polygon through geographical locations on the map.
   const Polygon({
     required this.polygonId,
@@ -123,11 +123,13 @@
   }
 
   /// Creates a new [Polygon] object whose values are the same as this instance.
+  @override
   Polygon clone() {
     return copyWith(pointsParam: List<LatLng>.of(points));
   }
 
   /// Converts this object to something serializable in JSON.
+  @override
   Object toJson() {
     final Map<String, Object> json = <String, Object>{};
 
@@ -159,19 +161,23 @@
 
   @override
   bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final Polygon typedOther = other as Polygon;
-    return polygonId == typedOther.polygonId &&
-        consumeTapEvents == typedOther.consumeTapEvents &&
-        fillColor == typedOther.fillColor &&
-        geodesic == typedOther.geodesic &&
-        listEquals(points, typedOther.points) &&
-        const DeepCollectionEquality().equals(holes, typedOther.holes) &&
-        visible == typedOther.visible &&
-        strokeColor == typedOther.strokeColor &&
-        strokeWidth == typedOther.strokeWidth &&
-        zIndex == typedOther.zIndex;
+    if (identical(this, other)) {
+      return true;
+    }
+    if (other.runtimeType != runtimeType) {
+      return false;
+    }
+    return other is Polygon &&
+        polygonId == other.polygonId &&
+        consumeTapEvents == other.consumeTapEvents &&
+        fillColor == other.fillColor &&
+        geodesic == other.geodesic &&
+        listEquals(points, other.points) &&
+        const DeepCollectionEquality().equals(holes, other.holes) &&
+        visible == other.visible &&
+        strokeColor == other.strokeColor &&
+        strokeWidth == other.strokeWidth &&
+        zIndex == other.zIndex;
   }
 
   @override
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart
index 00c7186..39e62e3 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart
@@ -21,7 +21,7 @@
 
 /// Draws a line through geographical locations on the map.
 @immutable
-class Polyline implements MapsObject {
+class Polyline implements MapsObject<Polyline> {
   /// Creates an immutable object representing a line drawn through geographical locations on the map.
   const Polyline({
     required this.polylineId,
@@ -150,6 +150,7 @@
 
   /// Creates a new [Polyline] object whose values are the same as this
   /// instance.
+  @override
   Polyline clone() {
     return copyWith(
       patternsParam: List<PatternItem>.of(patterns),
@@ -158,6 +159,7 @@
   }
 
   /// Converts this object to something serializable in JSON.
+  @override
   Object toJson() {
     final Map<String, Object> json = <String, Object>{};
 
@@ -191,21 +193,25 @@
 
   @override
   bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (other.runtimeType != runtimeType) return false;
-    final Polyline typedOther = other as Polyline;
-    return polylineId == typedOther.polylineId &&
-        consumeTapEvents == typedOther.consumeTapEvents &&
-        color == typedOther.color &&
-        geodesic == typedOther.geodesic &&
-        jointType == typedOther.jointType &&
-        listEquals(patterns, typedOther.patterns) &&
-        listEquals(points, typedOther.points) &&
-        startCap == typedOther.startCap &&
-        endCap == typedOther.endCap &&
-        visible == typedOther.visible &&
-        width == typedOther.width &&
-        zIndex == typedOther.zIndex;
+    if (identical(this, other)) {
+      return true;
+    }
+    if (other.runtimeType != runtimeType) {
+      return false;
+    }
+    return other is Polyline &&
+        polylineId == other.polylineId &&
+        consumeTapEvents == other.consumeTapEvents &&
+        color == other.color &&
+        geodesic == other.geodesic &&
+        jointType == other.jointType &&
+        listEquals(patterns, other.patterns) &&
+        listEquals(points, other.points) &&
+        startCap == other.startCap &&
+        endCap == other.endCap &&
+        visible == other.visible &&
+        width == other.width &&
+        zIndex == other.zIndex;
   }
 
   @override
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/screen_coordinate.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/screen_coordinate.dart
index b424aa5..b1d37dc 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/screen_coordinate.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/screen_coordinate.dart
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'package:flutter/foundation.dart' show immutable;
+import 'package:flutter/foundation.dart' show immutable, objectRuntimeType;
 
 /// Represents a point coordinate in the [GoogleMap]'s view.
 ///
@@ -26,17 +26,17 @@
   /// Converts this object to something serializable in JSON.
   Object toJson() {
     return <String, int>{
-      "x": x,
-      "y": y,
+      'x': x,
+      'y': y,
     };
   }
 
   @override
-  String toString() => '$runtimeType($x, $y)';
+  String toString() => '${objectRuntimeType(this, 'ScreenCoordinate')}($x, $y)';
 
   @override
-  bool operator ==(Object o) {
-    return o is ScreenCoordinate && o.x == x && o.y == y;
+  bool operator ==(Object other) {
+    return other is ScreenCoordinate && other.x == x && other.y == y;
   }
 
   @override
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart
index 80b0527..aaf0f80 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart
@@ -41,8 +41,8 @@
 /// The coordinates of the tiles are measured from the top left (northwest) corner of the map.
 /// At zoom level N, the x values of the tile coordinates range from 0 to 2N - 1 and increase from
 /// west to east and the y values range from 0 to 2N - 1 and increase from north to south.
-///
-class TileOverlay implements MapsObject {
+@immutable
+class TileOverlay implements MapsObject<TileOverlay> {
   /// Creates an immutable representation of a [TileOverlay] to draw on [GoogleMap].
   const TileOverlay({
     required this.tileOverlayId,
@@ -106,9 +106,11 @@
     );
   }
 
+  @override
   TileOverlay clone() => copyWith();
 
   /// Converts this object to JSON.
+  @override
   Object toJson() {
     final Map<String, Object> json = <String, Object>{};
 
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart
index 5e2e4c2..1e1bef8 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart
@@ -7,25 +7,24 @@
 export 'callbacks.dart';
 export 'camera.dart';
 export 'cap.dart';
-export 'circle_updates.dart';
 export 'circle.dart';
+export 'circle_updates.dart';
 export 'joint_type.dart';
 export 'location.dart';
-export 'maps_object_updates.dart';
 export 'maps_object.dart';
-export 'marker_updates.dart';
+export 'maps_object_updates.dart';
 export 'marker.dart';
+export 'marker_updates.dart';
 export 'pattern_item.dart';
-export 'polygon_updates.dart';
 export 'polygon.dart';
-export 'polyline_updates.dart';
+export 'polygon_updates.dart';
 export 'polyline.dart';
+export 'polyline_updates.dart';
 export 'screen_coordinate.dart';
 export 'tile.dart';
 export 'tile_overlay.dart';
 export 'tile_provider.dart';
 export 'ui.dart';
-
 // Export the utils, they're used by the Widget
 export 'utils/circle.dart';
 export 'utils/marker.dart';
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/ui.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/ui.dart
index 18f88b9..482f64b 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/ui.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/ui.dart
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'package:flutter/foundation.dart';
+
 import 'types.dart';
 
 /// Type of map tiles to display.
@@ -29,6 +31,7 @@
 // Used with [GoogleMapOptions] to wrap a [LatLngBounds] value. This allows
 // distinguishing between specifying an unbounded target (null `LatLngBounds`)
 // from not specifying anything (null `CameraTargetBounds`).
+@immutable
 class CameraTargetBounds {
   /// Creates a camera target bounds with the specified bounding box, or null
   /// to indicate that the camera target is not bounded.
@@ -47,10 +50,13 @@
 
   @override
   bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (runtimeType != other.runtimeType) return false;
-    final CameraTargetBounds typedOther = other as CameraTargetBounds;
-    return bounds == typedOther.bounds;
+    if (identical(this, other)) {
+      return true;
+    }
+    if (runtimeType != other.runtimeType) {
+      return false;
+    }
+    return other is CameraTargetBounds && bounds == other.bounds;
   }
 
   @override
@@ -66,6 +72,7 @@
 // Used with [GoogleMapOptions] to wrap min and max zoom. This allows
 // distinguishing between specifying unbounded zooming (null `minZoom` and
 // `maxZoom`) from not specifying anything (null `MinMaxZoomPreference`).
+@immutable
 class MinMaxZoomPreference {
   /// Creates a immutable representation of the preferred minimum and maximum zoom values for the map camera.
   ///
@@ -88,10 +95,15 @@
 
   @override
   bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    if (runtimeType != other.runtimeType) return false;
-    final MinMaxZoomPreference typedOther = other as MinMaxZoomPreference;
-    return minZoom == typedOther.minZoom && maxZoom == typedOther.maxZoom;
+    if (identical(this, other)) {
+      return true;
+    }
+    if (runtimeType != other.runtimeType) {
+      return false;
+    }
+    return other is MinMaxZoomPreference &&
+        minZoom == other.minZoom &&
+        maxZoom == other.maxZoom;
   }
 
   @override
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/maps_object.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/maps_object.dart
index da5a498..d17dbd2 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/maps_object.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/maps_object.dart
@@ -5,14 +5,13 @@
 import '../maps_object.dart';
 
 /// Converts an [Iterable] of [MapsObject]s in a Map of [MapObjectId] -> [MapObject].
-Map<MapsObjectId<T>, T> keyByMapsObjectId<T extends MapsObject>(
+Map<MapsObjectId<T>, T> keyByMapsObjectId<T extends MapsObject<T>>(
     Iterable<T> objects) {
   return Map<MapsObjectId<T>, T>.fromEntries(objects.map((T object) =>
-      MapEntry<MapsObjectId<T>, T>(
-          object.mapsId as MapsObjectId<T>, object.clone())));
+      MapEntry<MapsObjectId<T>, T>(object.mapsId, object.clone())));
 }
 
 /// Converts a Set of [MapsObject]s into something serializable in JSON.
-Object serializeMapsObjectSet(Set<MapsObject> mapsObjects) {
-  return mapsObjects.map<Object>((MapsObject p) => p.toJson()).toList();
+Object serializeMapsObjectSet<T>(Set<MapsObject<T>> mapsObjects) {
+  return mapsObjects.map<Object>((MapsObject<T> p) => p.toJson()).toList();
 }
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml
index 998f319..759daf2 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml
@@ -4,7 +4,7 @@
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22
 # NOTE: We strongly prefer non-breaking changes, even at the expense of a
 # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
-version: 2.1.6
+version: 2.1.7
 
 environment:
   sdk: '>=2.12.0 <3.0.0'
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/method_channel/method_channel_google_maps_flutter_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/method_channel/method_channel_google_maps_flutter_test.dart
index 9ae42ce..e505218 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/method_channel/method_channel_google_maps_flutter_test.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/method_channel/method_channel_google_maps_flutter_test.dart
@@ -2,13 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'package:async/async.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_test/flutter_test.dart';
-
 import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
 
-import 'package:async/async.dart';
-
 void main() {
   TestWidgetsFlutterBinding.ensureInitialized();
 
@@ -39,8 +37,8 @@
       final ByteData byteData = const StandardMethodCodec()
           .encodeMethodCall(MethodCall(method, data));
       await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger
-          .handlePlatformMessage(
-              "plugins.flutter.io/google_maps_$mapId", byteData, (data) {});
+          .handlePlatformMessage('plugins.flutter.io/google_maps_$mapId',
+              byteData, (ByteData? data) {});
     }
 
     // Calls each method that uses invokeMethod with a return type other than
@@ -66,8 +64,8 @@
         }
       });
 
-      await maps.getLatLng(ScreenCoordinate(x: 0, y: 0), mapId: mapId);
-      await maps.isMarkerInfoWindowShown(MarkerId(''), mapId: mapId);
+      await maps.getLatLng(const ScreenCoordinate(x: 0, y: 0), mapId: mapId);
+      await maps.isMarkerInfoWindowShown(const MarkerId(''), mapId: mapId);
       await maps.getZoomLevel(mapId: mapId);
       await maps.takeSnapshot(mapId: mapId);
       // Check that all the invokeMethod calls happened.
@@ -80,20 +78,20 @@
     });
     test('markers send drag event to correct streams', () async {
       const int mapId = 1;
-      final jsonMarkerDragStartEvent = <dynamic, dynamic>{
-        "mapId": mapId,
-        "markerId": "drag-start-marker",
-        "position": <double>[1.0, 1.0]
+      final Map<dynamic, dynamic> jsonMarkerDragStartEvent = <dynamic, dynamic>{
+        'mapId': mapId,
+        'markerId': 'drag-start-marker',
+        'position': <double>[1.0, 1.0]
       };
-      final jsonMarkerDragEvent = <dynamic, dynamic>{
-        "mapId": mapId,
-        "markerId": "drag-marker",
-        "position": <double>[1.0, 1.0]
+      final Map<dynamic, dynamic> jsonMarkerDragEvent = <dynamic, dynamic>{
+        'mapId': mapId,
+        'markerId': 'drag-marker',
+        'position': <double>[1.0, 1.0]
       };
-      final jsonMarkerDragEndEvent = <dynamic, dynamic>{
-        "mapId": mapId,
-        "markerId": "drag-end-marker",
-        "position": <double>[1.0, 1.0]
+      final Map<dynamic, dynamic> jsonMarkerDragEndEvent = <dynamic, dynamic>{
+        'mapId': mapId,
+        'markerId': 'drag-end-marker',
+        'position': <double>[1.0, 1.0]
       };
 
       final MethodChannelGoogleMapsFlutter maps =
@@ -101,23 +99,24 @@
       maps.ensureChannelInitialized(mapId);
 
       final StreamQueue<MarkerDragStartEvent> markerDragStartStream =
-          StreamQueue(maps.onMarkerDragStart(mapId: mapId));
+          StreamQueue<MarkerDragStartEvent>(
+              maps.onMarkerDragStart(mapId: mapId));
       final StreamQueue<MarkerDragEvent> markerDragStream =
-          StreamQueue(maps.onMarkerDrag(mapId: mapId));
+          StreamQueue<MarkerDragEvent>(maps.onMarkerDrag(mapId: mapId));
       final StreamQueue<MarkerDragEndEvent> markerDragEndStream =
-          StreamQueue(maps.onMarkerDragEnd(mapId: mapId));
+          StreamQueue<MarkerDragEndEvent>(maps.onMarkerDragEnd(mapId: mapId));
 
       await sendPlatformMessage(
-          mapId, "marker#onDragStart", jsonMarkerDragStartEvent);
-      await sendPlatformMessage(mapId, "marker#onDrag", jsonMarkerDragEvent);
+          mapId, 'marker#onDragStart', jsonMarkerDragStartEvent);
+      await sendPlatformMessage(mapId, 'marker#onDrag', jsonMarkerDragEvent);
       await sendPlatformMessage(
-          mapId, "marker#onDragEnd", jsonMarkerDragEndEvent);
+          mapId, 'marker#onDragEnd', jsonMarkerDragEndEvent);
 
       expect((await markerDragStartStream.next).value.value,
-          equals("drag-start-marker"));
-      expect((await markerDragStream.next).value.value, equals("drag-marker"));
+          equals('drag-start-marker'));
+      expect((await markerDragStream.next).value.value, equals('drag-marker'));
       expect((await markerDragEndStream.next).value.value,
-          equals("drag-end-marker"));
+          equals('drag-end-marker'));
     });
   });
 }
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart
index bdbaff7..0899bb6 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart
@@ -6,11 +6,10 @@
 import 'package:flutter/foundation.dart';
 import 'package:flutter/gestures.dart';
 import 'package:flutter/services.dart';
-import 'package:mockito/mockito.dart';
 import 'package:flutter_test/flutter_test.dart';
-import 'package:plugin_platform_interface/plugin_platform_interface.dart';
-
 import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
+import 'package:mockito/mockito.dart';
+import 'package:plugin_platform_interface/plugin_platform_interface.dart';
 
 void main() {
   TestWidgetsFlutterBinding.ensureInitialized();
@@ -50,7 +49,8 @@
           platform.buildViewWithTextDirection(
             0,
             (_) {},
-            initialCameraPosition: CameraPosition(target: LatLng(0.0, 0.0)),
+            initialCameraPosition:
+                const CameraPosition(target: LatLng(0.0, 0.0)),
             textDirection: TextDirection.ltr,
           ),
           isA<Text>(),
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/bitmap_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/bitmap_test.dart
index 6d02b2c..7fbaf49 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/bitmap_test.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/bitmap_test.dart
@@ -13,13 +13,14 @@
 
   group('$BitmapDescriptor', () {
     test('toJson / fromJson', () {
-      final descriptor =
+      final BitmapDescriptor descriptor =
           BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueCyan);
-      final json = descriptor.toJson();
+      final Object json = descriptor.toJson();
 
       // Rehydrate a new bitmap descriptor...
       // ignore: deprecated_member_use_from_same_package
-      final descriptorFromJson = BitmapDescriptor.fromJson(json);
+      final BitmapDescriptor descriptorFromJson =
+          BitmapDescriptor.fromJson(json);
 
       expect(descriptorFromJson, isNot(descriptor)); // New instance
       expect(identical(descriptorFromJson.toJson(), json), isTrue); // Same JSON
@@ -28,81 +29,85 @@
     group('fromJson validation', () {
       group('type validation', () {
         test('correct type', () {
-          expect(BitmapDescriptor.fromJson(['defaultMarker']),
+          expect(BitmapDescriptor.fromJson(<dynamic>['defaultMarker']),
               isA<BitmapDescriptor>());
         });
         test('wrong type', () {
           expect(() {
-            BitmapDescriptor.fromJson(['bogusType']);
+            BitmapDescriptor.fromJson(<dynamic>['bogusType']);
           }, throwsAssertionError);
         });
       });
       group('defaultMarker', () {
         test('hue is null', () {
-          expect(BitmapDescriptor.fromJson(['defaultMarker']),
+          expect(BitmapDescriptor.fromJson(<dynamic>['defaultMarker']),
               isA<BitmapDescriptor>());
         });
         test('hue is number', () {
-          expect(BitmapDescriptor.fromJson(['defaultMarker', 158]),
+          expect(BitmapDescriptor.fromJson(<dynamic>['defaultMarker', 158]),
               isA<BitmapDescriptor>());
         });
         test('hue is not number', () {
           expect(() {
-            BitmapDescriptor.fromJson(['defaultMarker', 'nope']);
+            BitmapDescriptor.fromJson(<dynamic>['defaultMarker', 'nope']);
           }, throwsAssertionError);
         });
         test('hue is out of range', () {
           expect(() {
-            BitmapDescriptor.fromJson(['defaultMarker', -1]);
+            BitmapDescriptor.fromJson(<dynamic>['defaultMarker', -1]);
           }, throwsAssertionError);
           expect(() {
-            BitmapDescriptor.fromJson(['defaultMarker', 361]);
+            BitmapDescriptor.fromJson(<dynamic>['defaultMarker', 361]);
           }, throwsAssertionError);
         });
       });
       group('fromBytes', () {
         test('with bytes', () {
           expect(
-              BitmapDescriptor.fromJson([
+              BitmapDescriptor.fromJson(<dynamic>[
                 'fromBytes',
-                Uint8List.fromList([1, 2, 3])
+                Uint8List.fromList(<int>[1, 2, 3])
               ]),
               isA<BitmapDescriptor>());
         });
         test('without bytes', () {
           expect(() {
-            BitmapDescriptor.fromJson(['fromBytes', null]);
+            BitmapDescriptor.fromJson(<dynamic>['fromBytes', null]);
           }, throwsAssertionError);
           expect(() {
-            BitmapDescriptor.fromJson(['fromBytes', []]);
+            BitmapDescriptor.fromJson(<dynamic>['fromBytes', <dynamic>[]]);
           }, throwsAssertionError);
         });
       });
       group('fromAsset', () {
         test('name is passed', () {
-          expect(BitmapDescriptor.fromJson(['fromAsset', 'some/path.png']),
+          expect(
+              BitmapDescriptor.fromJson(
+                  <dynamic>['fromAsset', 'some/path.png']),
               isA<BitmapDescriptor>());
         });
         test('name cannot be null or empty', () {
           expect(() {
-            BitmapDescriptor.fromJson(['fromAsset', null]);
+            BitmapDescriptor.fromJson(<dynamic>['fromAsset', null]);
           }, throwsAssertionError);
           expect(() {
-            BitmapDescriptor.fromJson(['fromAsset', '']);
+            BitmapDescriptor.fromJson(<dynamic>['fromAsset', '']);
           }, throwsAssertionError);
         });
         test('package is passed', () {
           expect(
               BitmapDescriptor.fromJson(
-                  ['fromAsset', 'some/path.png', 'some_package']),
+                  <dynamic>['fromAsset', 'some/path.png', 'some_package']),
               isA<BitmapDescriptor>());
         });
         test('package cannot be null or empty', () {
           expect(() {
-            BitmapDescriptor.fromJson(['fromAsset', 'some/path.png', null]);
+            BitmapDescriptor.fromJson(
+                <dynamic>['fromAsset', 'some/path.png', null]);
           }, throwsAssertionError);
           expect(() {
-            BitmapDescriptor.fromJson(['fromAsset', 'some/path.png', '']);
+            BitmapDescriptor.fromJson(
+                <dynamic>['fromAsset', 'some/path.png', '']);
           }, throwsAssertionError);
         });
       });
@@ -110,34 +115,34 @@
         test('name and dpi passed', () {
           expect(
               BitmapDescriptor.fromJson(
-                  ['fromAssetImage', 'some/path.png', 1.0]),
+                  <dynamic>['fromAssetImage', 'some/path.png', 1.0]),
               isA<BitmapDescriptor>());
         });
         test('name cannot be null or empty', () {
           expect(() {
-            BitmapDescriptor.fromJson(['fromAssetImage', null, 1.0]);
+            BitmapDescriptor.fromJson(<dynamic>['fromAssetImage', null, 1.0]);
           }, throwsAssertionError);
           expect(() {
-            BitmapDescriptor.fromJson(['fromAssetImage', '', 1.0]);
+            BitmapDescriptor.fromJson(<dynamic>['fromAssetImage', '', 1.0]);
           }, throwsAssertionError);
         });
         test('dpi must be number', () {
           expect(() {
             BitmapDescriptor.fromJson(
-                ['fromAssetImage', 'some/path.png', null]);
+                <dynamic>['fromAssetImage', 'some/path.png', null]);
           }, throwsAssertionError);
           expect(() {
             BitmapDescriptor.fromJson(
-                ['fromAssetImage', 'some/path.png', 'one']);
+                <dynamic>['fromAssetImage', 'some/path.png', 'one']);
           }, throwsAssertionError);
         });
         test('with optional [width, height] List', () {
           expect(
-              BitmapDescriptor.fromJson([
+              BitmapDescriptor.fromJson(<dynamic>[
                 'fromAssetImage',
                 'some/path.png',
                 1.0,
-                [640, 480]
+                <dynamic>[640, 480]
               ]),
               isA<BitmapDescriptor>());
         });
@@ -146,18 +151,18 @@
             () {
           expect(() {
             BitmapDescriptor.fromJson(
-                ['fromAssetImage', 'some/path.png', 1.0, null]);
+                <dynamic>['fromAssetImage', 'some/path.png', 1.0, null]);
           }, throwsAssertionError);
           expect(() {
             BitmapDescriptor.fromJson(
-                ['fromAssetImage', 'some/path.png', 1.0, []]);
+                <dynamic>['fromAssetImage', 'some/path.png', 1.0, <dynamic>[]]);
           }, throwsAssertionError);
           expect(() {
-            BitmapDescriptor.fromJson([
+            BitmapDescriptor.fromJson(<dynamic>[
               'fromAssetImage',
               'some/path.png',
               1.0,
-              [640, 480, 1024]
+              <dynamic>[640, 480, 1024]
             ]);
           }, throwsAssertionError);
         });
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart
index 11665d9..70e57aa 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart
@@ -9,13 +9,14 @@
   TestWidgetsFlutterBinding.ensureInitialized();
 
   test('toMap / fromMap', () {
-    const cameraPosition = CameraPosition(
+    const CameraPosition cameraPosition = CameraPosition(
         target: LatLng(10.0, 15.0), bearing: 0.5, tilt: 30.0, zoom: 1.5);
     // Cast to <dynamic, dynamic> to ensure that recreating from JSON, where
     // type information will have likely been lost, still works.
-    final json = (cameraPosition.toMap() as Map<String, dynamic>)
-        .cast<dynamic, dynamic>();
-    final cameraPositionFromJson = CameraPosition.fromMap(json);
+    final Map<dynamic, dynamic> json =
+        (cameraPosition.toMap() as Map<String, dynamic>)
+            .cast<dynamic, dynamic>();
+    final CameraPosition? cameraPositionFromJson = CameraPosition.fromMap(json);
 
     expect(cameraPosition, cameraPositionFromJson);
   });
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/location_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/location_test.dart
index 80f6961..9da3e54 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/location_test.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/location_test.dart
@@ -10,50 +10,50 @@
 
   group('LanLng constructor', () {
     test('Maintains longitude precision if within acceptable range', () async {
-      const lat = -34.509981;
-      const lng = 150.792384;
+      const double lat = -34.509981;
+      const double lng = 150.792384;
 
-      final latLng = LatLng(lat, lng);
+      const LatLng latLng = LatLng(lat, lng);
 
       expect(latLng.latitude, equals(lat));
       expect(latLng.longitude, equals(lng));
     });
 
     test('Normalizes longitude that is below lower limit', () async {
-      const lat = -34.509981;
-      const lng = -270.0;
+      const double lat = -34.509981;
+      const double lng = -270.0;
 
-      final latLng = LatLng(lat, lng);
+      const LatLng latLng = LatLng(lat, lng);
 
       expect(latLng.latitude, equals(lat));
       expect(latLng.longitude, equals(90.0));
     });
 
     test('Normalizes longitude that is above upper limit', () async {
-      const lat = -34.509981;
-      const lng = 270.0;
+      const double lat = -34.509981;
+      const double lng = 270.0;
 
-      final latLng = LatLng(lat, lng);
+      const LatLng latLng = LatLng(lat, lng);
 
       expect(latLng.latitude, equals(lat));
       expect(latLng.longitude, equals(-90.0));
     });
 
     test('Includes longitude set to lower limit', () async {
-      const lat = -34.509981;
-      const lng = -180.0;
+      const double lat = -34.509981;
+      const double lng = -180.0;
 
-      final latLng = LatLng(lat, lng);
+      const LatLng latLng = LatLng(lat, lng);
 
       expect(latLng.latitude, equals(lat));
       expect(latLng.longitude, equals(-180.0));
     });
 
     test('Normalizes longitude set to upper limit', () async {
-      const lat = -34.509981;
-      const lng = 180.0;
+      const double lat = -34.509981;
+      const double lng = 180.0;
 
-      final latLng = LatLng(lat, lng);
+      const LatLng latLng = LatLng(lat, lng);
 
       expect(latLng.latitude, equals(lat));
       expect(latLng.longitude, equals(-180.0));
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart
index c2ca2bd..7c5106c 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart
@@ -37,9 +37,9 @@
     expect(
         serializeMapsObjectSet(<TestMapsObject>{object1, object2, object3}),
         <Map<String, Object>>[
-          {'id': '1'},
-          {'id': '2'},
-          {'id': '3'}
+          <String, Object>{'id': '1'},
+          <String, Object>{'id': '2'},
+          <String, Object>{'id': '3'}
         ]);
   });
 }
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart
index 73ed1d9..414196b 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart
@@ -30,24 +30,25 @@
           TestMapsObject(MapsObjectId<TestMapsObject>('id3'), data: 2);
       const TestMapsObject to4 =
           TestMapsObject(MapsObjectId<TestMapsObject>('id4'));
-      final Set<TestMapsObject> previous =
-          Set.from(<TestMapsObject>[to1, to2, to3]);
-      final Set<TestMapsObject> current =
-          Set.from(<TestMapsObject>[to2, to3Changed, to4]);
+      final Set<TestMapsObject> previous = <TestMapsObject>{to1, to2, to3};
+      final Set<TestMapsObject> current = <TestMapsObject>{
+        to2,
+        to3Changed,
+        to4
+      };
       final TestMapsObjectUpdate updates =
           TestMapsObjectUpdate.from(previous, current);
 
       final Set<MapsObjectId<TestMapsObject>> toRemove =
-          Set.from(<MapsObjectId<TestMapsObject>>[
+          <MapsObjectId<TestMapsObject>>{
         const MapsObjectId<TestMapsObject>('id1')
-      ]);
+      };
       expect(updates.objectIdsToRemove, toRemove);
 
-      final Set<TestMapsObject> toAdd = Set.from(<TestMapsObject>[to4]);
+      final Set<TestMapsObject> toAdd = <TestMapsObject>{to4};
       expect(updates.objectsToAdd, toAdd);
 
-      final Set<TestMapsObject> toChange =
-          Set.from(<TestMapsObject>[to3Changed]);
+      final Set<TestMapsObject> toChange = <TestMapsObject>{to3Changed};
       expect(updates.objectsToChange, toChange);
     });
 
@@ -62,10 +63,12 @@
           TestMapsObject(MapsObjectId<TestMapsObject>('id3'), data: 2);
       const TestMapsObject to4 =
           TestMapsObject(MapsObjectId<TestMapsObject>('id4'));
-      final Set<TestMapsObject> previous =
-          Set.from(<TestMapsObject>[to1, to2, to3]);
-      final Set<TestMapsObject> current =
-          Set.from(<TestMapsObject>[to2, to3Changed, to4]);
+      final Set<TestMapsObject> previous = <TestMapsObject>{to1, to2, to3};
+      final Set<TestMapsObject> current = <TestMapsObject>{
+        to2,
+        to3Changed,
+        to4
+      };
       final TestMapsObjectUpdate updates =
           TestMapsObjectUpdate.from(previous, current);
 
@@ -90,13 +93,18 @@
           TestMapsObject(MapsObjectId<TestMapsObject>('id3'), data: 2);
       const TestMapsObject to4 =
           TestMapsObject(MapsObjectId<TestMapsObject>('id4'));
-      final Set<TestMapsObject> previous =
-          Set.from(<TestMapsObject>[to1, to2, to3]);
-      final Set<TestMapsObject> current1 =
-          Set.from(<TestMapsObject>[to2, to3Changed, to4]);
-      final Set<TestMapsObject> current2 =
-          Set.from(<TestMapsObject>[to2, to3Changed, to4]);
-      final Set<TestMapsObject> current3 = Set.from(<TestMapsObject>[to2, to4]);
+      final Set<TestMapsObject> previous = <TestMapsObject>{to1, to2, to3};
+      final Set<TestMapsObject> current1 = <TestMapsObject>{
+        to2,
+        to3Changed,
+        to4
+      };
+      final Set<TestMapsObject> current2 = <TestMapsObject>{
+        to2,
+        to3Changed,
+        to4
+      };
+      final Set<TestMapsObject> current3 = <TestMapsObject>{to2, to4};
       final TestMapsObjectUpdate updates1 =
           TestMapsObjectUpdate.from(previous, current1);
       final TestMapsObjectUpdate updates2 =
@@ -118,10 +126,12 @@
           TestMapsObject(MapsObjectId<TestMapsObject>('id3'), data: 2);
       const TestMapsObject to4 =
           TestMapsObject(MapsObjectId<TestMapsObject>('id4'));
-      final Set<TestMapsObject> previous =
-          Set.from(<TestMapsObject>[to1, to2, to3]);
-      final Set<TestMapsObject> current =
-          Set.from(<TestMapsObject>[to2, to3Changed, to4]);
+      final Set<TestMapsObject> previous = <TestMapsObject>{to1, to2, to3};
+      final Set<TestMapsObject> current = <TestMapsObject>{
+        to2,
+        to3Changed,
+        to4
+      };
       final TestMapsObjectUpdate updates =
           TestMapsObjectUpdate.from(previous, current);
       expect(
@@ -143,10 +153,12 @@
           TestMapsObject(MapsObjectId<TestMapsObject>('id3'), data: 2);
       const TestMapsObject to4 =
           TestMapsObject(MapsObjectId<TestMapsObject>('id4'));
-      final Set<TestMapsObject> previous =
-          Set.from(<TestMapsObject>[to1, to2, to3]);
-      final Set<TestMapsObject> current =
-          Set.from(<TestMapsObject>[to2, to3Changed, to4]);
+      final Set<TestMapsObject> previous = <TestMapsObject>{to1, to2, to3};
+      final Set<TestMapsObject> current = <TestMapsObject>{
+        to2,
+        to3Changed,
+        to4
+      };
       final TestMapsObjectUpdate updates =
           TestMapsObjectUpdate.from(previous, current);
       expect(
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/marker_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/marker_test.dart
index c8f6fa5..db7afcb 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/marker_test.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/marker_test.dart
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'package:flutter/cupertino.dart';
 import 'package:flutter_test/flutter_test.dart';
 
 import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
@@ -12,7 +11,7 @@
 
   group('$Marker', () {
     test('constructor defaults', () {
-      final Marker marker = Marker(markerId: MarkerId("ABC123"));
+      const Marker marker = Marker(markerId: MarkerId('ABC123'));
 
       expect(marker.alpha, equals(1.0));
       expect(marker.anchor, equals(const Offset(0.5, 1.0)));
@@ -31,9 +30,10 @@
       expect(marker.onDragEnd, equals(null));
     });
     test('constructor alpha is >= 0.0 and <= 1.0', () {
-      final ValueSetter<double> initWithAlpha = (double alpha) {
-        Marker(markerId: MarkerId("ABC123"), alpha: alpha);
-      };
+      void initWithAlpha(double alpha) {
+        Marker(markerId: const MarkerId('ABC123'), alpha: alpha);
+      }
+
       expect(() => initWithAlpha(-0.5), throwsAssertionError);
       expect(() => initWithAlpha(0.0), isNot(throwsAssertionError));
       expect(() => initWithAlpha(0.5), isNot(throwsAssertionError));
@@ -45,19 +45,19 @@
       final BitmapDescriptor testDescriptor =
           BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueCyan);
       final Marker marker = Marker(
-        markerId: MarkerId("ABC123"),
+        markerId: const MarkerId('ABC123'),
         alpha: 0.12345,
-        anchor: Offset(100, 100),
+        anchor: const Offset(100, 100),
         consumeTapEvents: true,
         draggable: true,
         flat: true,
         icon: testDescriptor,
-        infoWindow: InfoWindow(
-          title: "Test title",
-          snippet: "Test snippet",
+        infoWindow: const InfoWindow(
+          title: 'Test title',
+          snippet: 'Test snippet',
           anchor: Offset(100, 200),
         ),
-        position: LatLng(50, 50),
+        position: const LatLng(50, 50),
         rotation: 100,
         visible: false,
         zIndex: 100,
@@ -70,7 +70,7 @@
       final Map<String, Object> json = marker.toJson() as Map<String, Object>;
 
       expect(json, <String, Object>{
-        'markerId': "ABC123",
+        'markerId': 'ABC123',
         'alpha': 0.12345,
         'anchor': <double>[100, 100],
         'consumeTapEvents': true,
@@ -78,8 +78,8 @@
         'flat': true,
         'icon': testDescriptor.toJson(),
         'infoWindow': <String, Object>{
-          'title': "Test title",
-          'snippet': "Test snippet",
+          'title': 'Test title',
+          'snippet': 'Test snippet',
           'anchor': <Object>[100.0, 200.0],
         },
         'position': <double>[50, 50],
@@ -89,31 +89,31 @@
       });
     });
     test('clone', () {
-      final Marker marker = Marker(markerId: MarkerId("ABC123"));
+      const Marker marker = Marker(markerId: MarkerId('ABC123'));
       final Marker clone = marker.clone();
 
       expect(identical(clone, marker), isFalse);
       expect(clone, equals(marker));
     });
     test('copyWith', () {
-      final Marker marker = Marker(markerId: MarkerId("ABC123"));
+      const Marker marker = Marker(markerId: MarkerId('ABC123'));
 
       final BitmapDescriptor testDescriptor =
           BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueCyan);
-      final double testAlphaParam = 0.12345;
-      final Offset testAnchorParam = Offset(100, 100);
+      const double testAlphaParam = 0.12345;
+      const Offset testAnchorParam = Offset(100, 100);
       final bool testConsumeTapEventsParam = !marker.consumeTapEvents;
       final bool testDraggableParam = !marker.draggable;
       final bool testFlatParam = !marker.flat;
       final BitmapDescriptor testIconParam = testDescriptor;
-      final InfoWindow testInfoWindowParam = InfoWindow(title: "Test");
-      final LatLng testPositionParam = LatLng(100, 100);
-      final double testRotationParam = 100;
+      const InfoWindow testInfoWindowParam = InfoWindow(title: 'Test');
+      const LatLng testPositionParam = LatLng(100, 100);
+      const double testRotationParam = 100;
       final bool testVisibleParam = !marker.visible;
-      final double testZIndexParam = 100;
-      final List<String> log = [];
+      const double testZIndexParam = 100;
+      final List<String> log = <String>[];
 
-      final copy = marker.copyWith(
+      final Marker copy = marker.copyWith(
         alphaParam: testAlphaParam,
         anchorParam: testAnchorParam,
         consumeTapEventsParam: testConsumeTapEventsParam,
@@ -126,16 +126,16 @@
         visibleParam: testVisibleParam,
         zIndexParam: testZIndexParam,
         onTapParam: () {
-          log.add("onTapParam");
+          log.add('onTapParam');
         },
         onDragStartParam: (LatLng latLng) {
-          log.add("onDragStartParam");
+          log.add('onDragStartParam');
         },
         onDragParam: (LatLng latLng) {
-          log.add("onDragParam");
+          log.add('onDragParam');
         },
         onDragEndParam: (LatLng latLng) {
-          log.add("onDragEndParam");
+          log.add('onDragEndParam');
         },
       );
 
@@ -152,16 +152,16 @@
       expect(copy.zIndex, equals(testZIndexParam));
 
       copy.onTap!();
-      expect(log, contains("onTapParam"));
+      expect(log, contains('onTapParam'));
 
-      copy.onDragStart!(LatLng(0, 1));
-      expect(log, contains("onDragStartParam"));
+      copy.onDragStart!(const LatLng(0, 1));
+      expect(log, contains('onDragStartParam'));
 
-      copy.onDrag!(LatLng(0, 1));
-      expect(log, contains("onDragParam"));
+      copy.onDrag!(const LatLng(0, 1));
+      expect(log, contains('onDragParam'));
 
-      copy.onDragEnd!(LatLng(0, 1));
-      expect(log, contains("onDragEndParam"));
+      copy.onDragEnd!(const LatLng(0, 1));
+      expect(log, contains('onDragEndParam'));
     });
   });
 }
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart
index e28da7a..0da077d 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart
@@ -2,13 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'package:flutter/foundation.dart';
 import 'package:google_maps_flutter_platform_interface/src/types/maps_object.dart';
 import 'package:google_maps_flutter_platform_interface/src/types/maps_object_updates.dart';
 
 /// A trivial TestMapsObject implementation for testing updates with.
-class TestMapsObject implements MapsObject {
+@immutable
+class TestMapsObject implements MapsObject<TestMapsObject> {
   const TestMapsObject(this.mapsId, {this.data = 1});
 
+  @override
   final MapsObjectId<TestMapsObject> mapsId;
 
   final int data;
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart
index c3ccf69..1a9a9d4 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart
@@ -8,7 +8,7 @@
 class _TestTileProvider extends TileProvider {
   @override
   Future<Tile> getTile(int x, int y, int? zoom) async {
-    return Tile(0, 0, null);
+    return const Tile(0, 0, null);
   }
 }
 
@@ -65,7 +65,7 @@
     test('equality', () async {
       final TileProvider tileProvider = _TestTileProvider();
       final TileOverlay tileOverlay1 = TileOverlay(
-          tileOverlayId: TileOverlayId('id1'),
+          tileOverlayId: const TileOverlayId('id1'),
           fadeIn: false,
           tileProvider: tileProvider,
           transparency: 0.1,
@@ -73,7 +73,7 @@
           visible: false,
           tileSize: 128);
       final TileOverlay tileOverlaySameValues = TileOverlay(
-          tileOverlayId: TileOverlayId('id1'),
+          tileOverlayId: const TileOverlayId('id1'),
           fadeIn: false,
           tileProvider: tileProvider,
           transparency: 0.1,
@@ -81,14 +81,14 @@
           visible: false,
           tileSize: 128);
       final TileOverlay tileOverlayDifferentId = TileOverlay(
-          tileOverlayId: TileOverlayId('id2'),
+          tileOverlayId: const TileOverlayId('id2'),
           fadeIn: false,
           tileProvider: tileProvider,
           transparency: 0.1,
           zIndex: 1,
           visible: false,
           tileSize: 128);
-      final TileOverlay tileOverlayDifferentProvider = TileOverlay(
+      const TileOverlay tileOverlayDifferentProvider = TileOverlay(
           tileOverlayId: TileOverlayId('id1'),
           fadeIn: false,
           tileProvider: null,
@@ -105,7 +105,7 @@
       final TileProvider tileProvider = _TestTileProvider();
       // Set non-default values for every parameter.
       final TileOverlay tileOverlay = TileOverlay(
-          tileOverlayId: TileOverlayId('id1'),
+          tileOverlayId: const TileOverlayId('id1'),
           fadeIn: false,
           tileProvider: tileProvider,
           transparency: 0.1,
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart
index fbb345c..b62f732 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart
@@ -18,20 +18,20 @@
       const TileOverlay to3Changed =
           TileOverlay(tileOverlayId: TileOverlayId('id3'), transparency: 0.5);
       const TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4'));
-      final Set<TileOverlay> previous = Set.from(<TileOverlay>[to1, to2, to3]);
-      final Set<TileOverlay> current =
-          Set.from(<TileOverlay>[to2, to3Changed, to4]);
+      final Set<TileOverlay> previous = <TileOverlay>{to1, to2, to3};
+      final Set<TileOverlay> current = <TileOverlay>{to2, to3Changed, to4};
       final TileOverlayUpdates updates =
           TileOverlayUpdates.from(previous, current);
 
-      final Set<TileOverlayId> toRemove =
-          Set.from(<TileOverlayId>[const TileOverlayId('id1')]);
+      final Set<TileOverlayId> toRemove = <TileOverlayId>{
+        const TileOverlayId('id1')
+      };
       expect(updates.tileOverlayIdsToRemove, toRemove);
 
-      final Set<TileOverlay> toAdd = Set.from(<TileOverlay>[to4]);
+      final Set<TileOverlay> toAdd = <TileOverlay>{to4};
       expect(updates.tileOverlaysToAdd, toAdd);
 
-      final Set<TileOverlay> toChange = Set.from(<TileOverlay>[to3Changed]);
+      final Set<TileOverlay> toChange = <TileOverlay>{to3Changed};
       expect(updates.tileOverlaysToChange, toChange);
     });
 
@@ -42,9 +42,8 @@
       const TileOverlay to3Changed =
           TileOverlay(tileOverlayId: TileOverlayId('id3'), transparency: 0.5);
       const TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4'));
-      final Set<TileOverlay> previous = Set.from(<TileOverlay>[to1, to2, to3]);
-      final Set<TileOverlay> current =
-          Set.from(<TileOverlay>[to2, to3Changed, to4]);
+      final Set<TileOverlay> previous = <TileOverlay>{to1, to2, to3};
+      final Set<TileOverlay> current = <TileOverlay>{to2, to3Changed, to4};
       final TileOverlayUpdates updates =
           TileOverlayUpdates.from(previous, current);
 
@@ -66,12 +65,10 @@
       const TileOverlay to3Changed =
           TileOverlay(tileOverlayId: TileOverlayId('id3'), transparency: 0.5);
       const TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4'));
-      final Set<TileOverlay> previous = Set.from(<TileOverlay>[to1, to2, to3]);
-      final Set<TileOverlay> current1 =
-          Set.from(<TileOverlay>[to2, to3Changed, to4]);
-      final Set<TileOverlay> current2 =
-          Set.from(<TileOverlay>[to2, to3Changed, to4]);
-      final Set<TileOverlay> current3 = Set.from(<TileOverlay>[to2, to4]);
+      final Set<TileOverlay> previous = <TileOverlay>{to1, to2, to3};
+      final Set<TileOverlay> current1 = <TileOverlay>{to2, to3Changed, to4};
+      final Set<TileOverlay> current2 = <TileOverlay>{to2, to3Changed, to4};
+      final Set<TileOverlay> current3 = <TileOverlay>{to2, to4};
       final TileOverlayUpdates updates1 =
           TileOverlayUpdates.from(previous, current1);
       final TileOverlayUpdates updates2 =
@@ -89,9 +86,8 @@
       const TileOverlay to3Changed =
           TileOverlay(tileOverlayId: TileOverlayId('id3'), transparency: 0.5);
       const TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4'));
-      final Set<TileOverlay> previous = Set.from(<TileOverlay>[to1, to2, to3]);
-      final Set<TileOverlay> current =
-          Set.from(<TileOverlay>[to2, to3Changed, to4]);
+      final Set<TileOverlay> previous = <TileOverlay>{to1, to2, to3};
+      final Set<TileOverlay> current = <TileOverlay>{to2, to3Changed, to4};
       final TileOverlayUpdates updates =
           TileOverlayUpdates.from(previous, current);
       expect(
@@ -109,9 +105,8 @@
       const TileOverlay to3Changed =
           TileOverlay(tileOverlayId: TileOverlayId('id3'), transparency: 0.5);
       const TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4'));
-      final Set<TileOverlay> previous = Set.from(<TileOverlay>[to1, to2, to3]);
-      final Set<TileOverlay> current =
-          Set.from(<TileOverlay>[to2, to3Changed, to4]);
+      final Set<TileOverlay> previous = <TileOverlay>{to1, to2, to3};
+      final Set<TileOverlay> current = <TileOverlay>{to2, to3Changed, to4};
       final TileOverlayUpdates updates =
           TileOverlayUpdates.from(previous, current);
       expect(
diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart
index 6539584..ab49fd1 100644
--- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart
@@ -12,7 +12,7 @@
 
   group('tile tests', () {
     test('toJson returns correct format', () async {
-      final Uint8List data = Uint8List.fromList([0, 1]);
+      final Uint8List data = Uint8List.fromList(<int>[0, 1]);
       final Tile tile = Tile(100, 200, data);
       final Object json = tile.toJson();
       expect(json, <String, Object>{
diff --git a/script/configs/custom_analysis.yaml b/script/configs/custom_analysis.yaml
index bcd7d37..f735019 100644
--- a/script/configs/custom_analysis.yaml
+++ b/script/configs/custom_analysis.yaml
@@ -1,14 +1,12 @@
 # Plugins that deliberately use their own analysis_options.yaml.
 #
-# This only exists to allow incrementally switching to the newer, stricter
-# analysis_options.yaml based on flutter/flutter, rather than the original
-# rules based on pedantic (now at analysis_options_legacy.yaml).
+# This only exists to allow incrementally adopting new analysis options in
+# cases where a new option can't be applied to the entire repository at
+# once. Do not add anything to this file without an issue reference and
+# a concrete plan for removing it relatively quickly.
 #
 # DO NOT move or delete this file without updating
 # https://github.com/dart-lang/sdk/blob/master/tools/bots/flutter/analyze_flutter_plugins.sh
 # which references this file from source, but out-of-repo.
 # Contact stuartmorgan or devoncarew for assistance if necessary.
 
-# TODO(ecosystem): Remove everything from this list. See:
-# https://github.com/flutter/flutter/issues/76229
-- google_maps_flutter/google_maps_flutter_platform_interface
diff --git a/script/tool/CHANGELOG.md b/script/tool/CHANGELOG.md
index 4b40aec..adc7bfc 100644
--- a/script/tool/CHANGELOG.md
+++ b/script/tool/CHANGELOG.md
@@ -1,3 +1,7 @@
+## NEXT
+
+- Supports empty custom analysis allow list files.
+
 ## 0.8.6
 
 - Adds `update-release-info` to apply changelog and optional version changes
diff --git a/script/tool/lib/src/analyze_command.dart b/script/tool/lib/src/analyze_command.dart
index 1cd85af..8778b3d 100644
--- a/script/tool/lib/src/analyze_command.dart
+++ b/script/tool/lib/src/analyze_command.dart
@@ -87,9 +87,11 @@
         getStringListArg(_customAnalysisFlag).expand<String>((String item) {
       if (item.endsWith('.yaml')) {
         final File file = packagesDir.fileSystem.file(item);
-        return (loadYaml(file.readAsStringSync()) as YamlList)
-            .toList()
-            .cast<String>();
+        final Object? yaml = loadYaml(file.readAsStringSync());
+        if (yaml == null) {
+          return <String>[];
+        }
+        return (yaml as YamlList).toList().cast<String>();
       }
       return <String>[item];
     }).toSet();
diff --git a/script/tool/test/analyze_command_test.dart b/script/tool/test/analyze_command_test.dart
index a9b8334..a4a47a2 100644
--- a/script/tool/test/analyze_command_test.dart
+++ b/script/tool/test/analyze_command_test.dart
@@ -213,6 +213,18 @@
           ]));
     });
 
+    test('allows an empty config file', () async {
+      createFakePlugin('foo', packagesDir,
+          extraFiles: <String>['analysis_options.yaml']);
+      final File allowFile = packagesDir.childFile('custom.yaml');
+      allowFile.createSync();
+
+      await expectLater(
+          () => runCapturingPrint(
+              runner, <String>['analyze', '--custom-analysis', allowFile.path]),
+          throwsA(isA<ToolExit>()));
+    });
+
     // See: https://github.com/flutter/flutter/issues/78994
     test('takes an empty allow list', () async {
       createFakePlugin('foo', packagesDir,