Minor doc, style, and perf updates to Navigator/Routes (#71689)

* Minor doc, style, and perf updates to Navigator/Routes

These are minor fixes I ended up making while working on a larger
project that never went anywhere.

- Used a ColoredBox instead of a DecoratedBox for ModalBarrier
  (probably a trivial memory/perf win).

- A bunch of Navigator documentation fixes around when things rebuild.

- Mark routes dirty when the Navigator has a dependency change. I
  cannot find a way to test this because as far as I can tell it makes
  no actual difference to when things rebuild because whenever the
  Navigator rebuilds the Overlay rebuilds and whenever that happens
  every OverlayEntry rebuilds, but in theory that's not guaranteed so
  this is sort of a correctness fix. It may even be a perf loss. We do
  something similar in didUpdateWidget already. I could be convinced
  to maybe remove these...

- Make ModalRoute.filter public like everything else.

- Made ModalRoute update its barrier when it gets an update, in case
  e.g. the modal barrier depends on inherited widgets via the
  navigator context. Again, not sure of any way to detect this, it
  might actually be moot, but it seems to be the technically correct
  solution?

- Minor style fixes.

All in all I couldn't figure out a way to test any of this (I wrote
multiple large tests but it turns out they all already pass on master
and are effectively redundant with existing tests).

* Remove extraneous blank line
diff --git a/packages/flutter/lib/src/services/message_codecs.dart b/packages/flutter/lib/src/services/message_codecs.dart
index e1784c5..92f9d72 100644
--- a/packages/flutter/lib/src/services/message_codecs.dart
+++ b/packages/flutter/lib/src/services/message_codecs.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 'dart:convert';
 import 'dart:typed_data';
 
diff --git a/packages/flutter/lib/src/widgets/modal_barrier.dart b/packages/flutter/lib/src/widgets/modal_barrier.dart
index 3d1b693..31538bd 100644
--- a/packages/flutter/lib/src/widgets/modal_barrier.dart
+++ b/packages/flutter/lib/src/widgets/modal_barrier.dart
@@ -8,7 +8,6 @@
 import 'package:flutter/services.dart';
 
 import 'basic.dart';
-import 'container.dart';
 import 'debug.dart';
 import 'framework.dart';
 import 'gesture_detector.dart';
@@ -113,10 +112,8 @@
               opaque: true,
               child: ConstrainedBox(
                 constraints: const BoxConstraints.expand(),
-                child: color == null ? null : DecoratedBox(
-                  decoration: BoxDecoration(
-                    color: color,
-                  ),
+                child: color == null ? null : ColoredBox(
+                  color: color!,
                 ),
               ),
             ),
diff --git a/packages/flutter/lib/src/widgets/navigator.dart b/packages/flutter/lib/src/widgets/navigator.dart
index 88bae80..deef670 100644
--- a/packages/flutter/lib/src/widgets/navigator.dart
+++ b/packages/flutter/lib/src/widgets/navigator.dart
@@ -399,20 +399,30 @@
   ///
   /// See also:
   ///
-  ///  * [changedExternalState], which is called when the [Navigator] rebuilds.
+  ///  * [changedExternalState], which is called when the [Navigator] has
+  ///    updated in some manner that might affect the routes.
   @protected
   @mustCallSuper
   void changedInternalState() { }
 
-  /// Called whenever the [Navigator] has its widget rebuilt, to indicate that
-  /// the route may wish to rebuild as well.
+  /// Called whenever the [Navigator] has updated in some manner that might
+  /// affect routes, to indicate that the route may wish to rebuild as well.
   ///
-  /// This is called by the [Navigator] whenever the [NavigatorState]'s
-  /// [State.widget] changes, for example because the [MaterialApp] has been rebuilt.
-  /// This ensures that routes that directly refer to the state of the widget
-  /// that built the [MaterialApp] will be notified when that widget rebuilds,
-  /// since it would otherwise be difficult to notify the routes that state they
-  /// depend on may have changed.
+  /// This is called by the [Navigator] whenever the
+  /// [NavigatorState]'s [State.widget] changes (as in [State.didUpdateWidget]),
+  /// for example because the [MaterialApp] has been rebuilt. This
+  /// ensures that routes that directly refer to the state of the
+  /// widget that built the [MaterialApp] will be notified when that
+  /// widget rebuilds, since it would otherwise be difficult to notify
+  /// the routes that state they depend on may have changed.
+  ///
+  /// It is also called whenever the [Navigator]'s dependencies change
+  /// (as in [State.didChangeDependencies]). This allows routes to use the
+  /// [Navigator]'s context ([NavigatorState.context]), for example in
+  /// [ModalRoute.barrierColor], and update accordingly.
+  ///
+  /// The [ModalRoute] subclass overrides this to force the barrier
+  /// overlay to rebuild.
   ///
   /// See also:
   ///
@@ -3442,6 +3452,8 @@
   void didChangeDependencies() {
     super.didChangeDependencies();
     _updateHeroController(HeroControllerScope.of(context));
+    for (final _RouteEntry entry in _history)
+      entry.route.changedExternalState();
   }
 
   void _updateHeroController(HeroController? newHeroController) {
diff --git a/packages/flutter/lib/src/widgets/routes.dart b/packages/flutter/lib/src/widgets/routes.dart
index 17ef544..dc41b75 100644
--- a/packages/flutter/lib/src/widgets/routes.dart
+++ b/packages/flutter/lib/src/widgets/routes.dart
@@ -871,15 +871,14 @@
   /// Creates a route that blocks interaction with previous routes.
   ModalRoute({
     RouteSettings? settings,
-    ui.ImageFilter? filter,
-  }) : _filter = filter,
-       super(settings: settings);
+    this.filter,
+  }) : super(settings: settings);
 
   /// The filter to add to the barrier.
   ///
   /// If given, this filter will be applied to the modal barrier using
   /// [BackdropFilter]. This allows blur effects, for example.
-  final ui.ImageFilter? _filter;
+  final ui.ImageFilter? filter;
 
   // The API for general users of this class
 
@@ -1130,9 +1129,14 @@
   ///
   /// If [barrierDismissible] is false, then tapping the barrier has no effect.
   ///
-  /// If this getter would ever start returning a different value, the
-  /// [Route.changedInternalState] should be invoked so that the change can take
-  /// effect.
+  /// If this getter would ever start returning a different value,
+  /// either [changedInternalState] or [changedExternalState] should
+  /// be invoked so that the change can take effect.
+  ///
+  /// It is safe to use `navigator.context` to look up inherited
+  /// widgets here, because the [Navigator] calls
+  /// [changedExternalState] whenever its dependencies change, and
+  /// [changedExternalState] causes the modal barrier to rebuild.
   ///
   /// See also:
   ///
@@ -1154,6 +1158,15 @@
   /// If [semanticsDismissible] is false, then modal barrier semantics are
   /// excluded from the semantics tree and tapping on the modal barrier
   /// has no effect.
+  ///
+  /// If this getter would ever start returning a different value,
+  /// either [changedInternalState] or [changedExternalState] should
+  /// be invoked so that the change can take effect.
+  ///
+  /// It is safe to use `navigator.context` to look up inherited
+  /// widgets here, because the [Navigator] calls
+  /// [changedExternalState] whenever its dependencies change, and
+  /// [changedExternalState] causes the modal barrier to rebuild.
   bool get semanticsDismissible => true;
 
   /// {@template flutter.widgets.ModalRoute.barrierColor}
@@ -1174,22 +1187,24 @@
   /// transparent to the specified color.
   /// {@endtemplate}
   ///
-  /// If this getter would ever start returning a different color, the
-  /// [Route.changedInternalState] should be invoked so that the change can take
-  /// effect.
+  /// If this getter would ever start returning a different color, one
+  /// of the [changedInternalState] or [changedExternalState] methods
+  /// should be invoked so that the change can take effect.
+  ///
+  /// It is safe to use `navigator.context` to look up inherited
+  /// widgets here, because the [Navigator] calls
+  /// [changedExternalState] whenever its dependencies change, and
+  /// [changedExternalState] causes the modal barrier to rebuild.
   ///
   /// {@tool snippet}
   ///
-  /// It is safe to use `navigator.context` here. For example, to make
-  /// the barrier color use the theme's background color, one could say:
+  /// For example, to make the barrier color use the theme's
+  /// background color, one could say:
   ///
   /// ```dart
   /// Color get barrierColor => Theme.of(navigator.context).backgroundColor;
   /// ```
   ///
-  /// The [Navigator] causes the [ModalRoute]'s modal barrier overlay entry
-  /// to rebuild any time its dependencies change.
-  ///
   /// {@end-tool}
   ///
   /// See also:
@@ -1213,9 +1228,14 @@
   /// usually darkened by the modal barrier.
   /// {@endtemplate}
   ///
-  /// If this getter would ever start returning a different label, the
-  /// [Route.changedInternalState] should be invoked so that the change can take
-  /// effect.
+  /// If this getter would ever start returning a different label,
+  /// either [changedInternalState] or [changedExternalState] should
+  /// be invoked so that the change can take effect.
+  ///
+  /// It is safe to use `navigator.context` to look up inherited
+  /// widgets here, because the [Navigator] calls
+  /// [changedExternalState] whenever its dependencies change, and
+  /// [changedExternalState] causes the modal barrier to rebuild.
   ///
   /// See also:
   ///
@@ -1236,9 +1256,14 @@
   /// While the route is animating into position, the color is animated from
   /// transparent to the specified [barrierColor].
   ///
-  /// If this getter would ever start returning a different curve, the
-  /// [changedInternalState] should be invoked so that the change can take
-  /// effect.
+  /// If this getter would ever start returning a different curve,
+  /// either [changedInternalState] or [changedExternalState] should
+  /// be invoked so that the change can take effect.
+  ///
+  /// It is safe to use `navigator.context` to look up inherited
+  /// widgets here, because the [Navigator] calls
+  /// [changedExternalState] whenever its dependencies change, and
+  /// [changedExternalState] causes the modal barrier to rebuild.
   ///
   /// It defaults to [Curves.ease].
   ///
@@ -1451,6 +1476,7 @@
   @override
   void changedExternalState() {
     super.changedExternalState();
+    _modalBarrier.markNeedsBuild();
     if (_scopeKey.currentState != null)
       _scopeKey.currentState!._forceRebuildPage();
   }
@@ -1493,9 +1519,9 @@
         barrierSemanticsDismissible: semanticsDismissible,
       );
     }
-    if (_filter != null) {
+    if (filter != null) {
       barrier = BackdropFilter(
-        filter: _filter!,
+        filter: filter!,
         child: barrier,
       );
     }
diff --git a/packages/flutter/test/widgets/overlay_test.dart b/packages/flutter/test/widgets/overlay_test.dart
index 50ebfde..bbbb9f0 100644
--- a/packages/flutter/test/widgets/overlay_test.dart
+++ b/packages/flutter/test/widgets/overlay_test.dart
@@ -1039,7 +1039,7 @@
     final dynamic renderObject = tester.renderObject(find.byType(Overlay));
     expect(renderObject.clipBehavior, equals(Clip.hardEdge));
 
-    for(final Clip clip in Clip.values) {
+    for (final Clip clip in Clip.values) {
       await tester.pumpWidget(
         Directionality(
           textDirection: TextDirection.ltr,