Fix MouseTracker annotation leak (#28990)

* Fix MouseTracker annotation leak

Map's remove method is typed `remove(Object key)`, which can cause bugs.

Modified the existing test to check if the annotation has been removed
from MouseTracker.
diff --git a/packages/flutter/lib/src/gestures/mouse_tracking.dart b/packages/flutter/lib/src/gestures/mouse_tracking.dart
index 5c93d4f..90a28b5 100644
--- a/packages/flutter/lib/src/gestures/mouse_tracking.dart
+++ b/packages/flutter/lib/src/gestures/mouse_tracking.dart
@@ -124,7 +124,7 @@
     for (int deviceId in trackedAnnotation.activeDevices) {
       annotation.onExit(PointerExitEvent.fromHoverEvent(_lastMouseEvent[deviceId]));
     }
-    _trackedAnnotations.remove(trackedAnnotation);
+    _trackedAnnotations.remove(annotation);
   }
 
   void _scheduleMousePositionCheck() {
@@ -171,6 +171,16 @@
     return trackedAnnotation;
   }
 
+  /// Checks if the given [MouseTrackerAnnotation] is attached to this
+  /// [MouseTracker].
+  ///
+  /// This function is only public to allow for proper testing of the
+  /// MouseTracker. Do not call in other contexts.
+  @visibleForTesting
+  bool isAnnotationAttached(MouseTrackerAnnotation annotation) {
+    return _trackedAnnotations[annotation] != null;
+  }
+
   /// Tells interested objects that a mouse has entered, exited, or moved, given
   /// a callback to fetch the [MouseTrackerAnnotation] associated with a global
   /// offset.
diff --git a/packages/flutter/lib/src/rendering/proxy_box.dart b/packages/flutter/lib/src/rendering/proxy_box.dart
index f5bb6d0..eb69561 100644
--- a/packages/flutter/lib/src/rendering/proxy_box.dart
+++ b/packages/flutter/lib/src/rendering/proxy_box.dart
@@ -2591,6 +2591,13 @@
   // Object used for annotation of the layer used for hover hit detection.
   MouseTrackerAnnotation _hoverAnnotation;
 
+  /// Object used for annotation of the layer used for hover hit detection.
+  ///
+  /// This is only public to allow for testing of Listener widgets. Do not call
+  /// in other contexts.
+  @visibleForTesting
+  MouseTrackerAnnotation get hoverAnnotation => _hoverAnnotation;
+
   void _updateAnnotations() {
     if (_hoverAnnotation != null && attached) {
       RendererBinding.instance.mouseTracker.detachAnnotation(_hoverAnnotation);
diff --git a/packages/flutter/test/widgets/listener_test.dart b/packages/flutter/test/widgets/listener_test.dart
index 1cde7a9..54f54e8 100644
--- a/packages/flutter/test/widgets/listener_test.dart
+++ b/packages/flutter/test/widgets/listener_test.dart
@@ -2,6 +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/rendering.dart';
 import 'package:flutter_test/flutter_test.dart';
 import 'package:flutter/widgets.dart';
 import 'package:flutter/gestures.dart';
@@ -109,6 +110,7 @@
           onPointerExit: (PointerExitEvent details) => exit = details,
         ),
       ));
+      final RenderPointerListener renderListener = tester.renderObject(find.byType(Listener));
       final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
       await gesture.moveTo(const Offset(400.0, 300.0));
       await tester.pump();
@@ -125,6 +127,7 @@
       ));
       expect(exit, isNotNull);
       expect(exit.position, equals(const Offset(400.0, 300.0)));
+      expect(tester.binding.mouseTracker.isAnnotationAttached(renderListener.hoverAnnotation), isFalse);
     });
   });
 }