Adds a banner warning users the legacy inspector will be removed (#9572)

diff --git a/packages/devtools_app/lib/src/screens/inspector/inspector_screen_body.dart b/packages/devtools_app/lib/src/screens/inspector/inspector_screen_body.dart
index ac6cd18..5ab577d 100644
--- a/packages/devtools_app/lib/src/screens/inspector/inspector_screen_body.dart
+++ b/packages/devtools_app/lib/src/screens/inspector/inspector_screen_body.dart
@@ -16,6 +16,7 @@
 import '../../shared/analytics/metrics.dart';
 import '../../shared/console/eval/inspector_tree.dart';
 import '../../shared/globals.dart';
+import '../../shared/managers/banner_messages.dart';
 import '../../shared/managers/error_badge_manager.dart';
 import '../../shared/primitives/blocking_action_mixin.dart';
 import '../../shared/ui/common_widgets.dart';
@@ -111,6 +112,8 @@
     }
 
     _summaryTreeController.setSearchTarget(searchTarget);
+
+    _showLegacyInspectorWarning(context);
   }
 
   @override
@@ -218,6 +221,12 @@
     _summaryTreeController.resetSearch();
   }
 
+  void _showLegacyInspectorWarning(BuildContext context) {
+    if (context.mounted) {
+      pushLegacyInspectorWarning(InspectorScreen.id);
+    }
+  }
+
   List<Widget> getServiceExtensionWidgets() {
     return [
       ServiceExtensionButtonGroup(
diff --git a/packages/devtools_app/lib/src/screens/inspector_shared/inspector_settings_dialog.dart b/packages/devtools_app/lib/src/screens/inspector_shared/inspector_settings_dialog.dart
index ebc3705..823a3dd 100644
--- a/packages/devtools_app/lib/src/screens/inspector_shared/inspector_settings_dialog.dart
+++ b/packages/devtools_app/lib/src/screens/inspector_shared/inspector_settings_dialog.dart
@@ -5,6 +5,7 @@
 import 'dart:async';
 
 import 'package:devtools_app_shared/ui.dart';
+import 'package:devtools_app_shared/utils.dart';
 import 'package:flutter/material.dart';
 import 'package:vm_service/vm_service.dart' hide Stack;
 
@@ -12,15 +13,38 @@
 import '../../shared/analytics/constants.dart' as gac;
 import '../../shared/feature_flags.dart';
 import '../../shared/globals.dart';
+import '../../shared/managers/banner_messages.dart';
 import '../../shared/preferences/preferences.dart';
 import '../../shared/primitives/simple_items.dart';
 import '../../shared/ui/common_widgets.dart';
 import '../../shared/ui/editable_list.dart';
+import 'inspector_screen.dart';
 
-class FlutterInspectorSettingsDialog extends StatelessWidget {
+class FlutterInspectorSettingsDialog extends StatefulWidget {
   const FlutterInspectorSettingsDialog({super.key});
 
   @override
+  State<FlutterInspectorSettingsDialog> createState() =>
+      _FlutterInspectorSettingsDialogState();
+}
+
+class _FlutterInspectorSettingsDialogState
+    extends State<FlutterInspectorSettingsDialog>
+    with AutoDisposeMixin {
+  @override
+  void initState() {
+    super.initState();
+    addAutoDisposeListener(preferences.inspector.legacyInspectorEnabled, () {
+      if (!preferences.inspector.legacyInspectorEnabled.value) {
+        bannerMessages.removeMessageByKey(
+          LegacyInspectorWarningMessage.buildKey(InspectorScreen.id),
+          InspectorScreen.id,
+        );
+      }
+    });
+  }
+
+  @override
   Widget build(BuildContext context) {
     final theme = Theme.of(context);
     const dialogHeight = 500.0;
@@ -74,7 +98,7 @@
                       title: 'Use legacy inspector',
                       description:
                           'Disable the redesigned Flutter inspector. Please know that '
-                          'the legacy inspector may be removed in a future release.',
+                          'the legacy inspector will be removed in a future release.',
                       gaItem: gac.inspectorV2Disabled,
                     ),
                   ),
diff --git a/packages/devtools_app/lib/src/shared/managers/banner_messages.dart b/packages/devtools_app/lib/src/shared/managers/banner_messages.dart
index 1597cf5..536dc11 100644
--- a/packages/devtools_app/lib/src/shared/managers/banner_messages.dart
+++ b/packages/devtools_app/lib/src/shared/managers/banner_messages.dart
@@ -521,6 +521,34 @@
       );
 }
 
+class LegacyInspectorWarningMessage extends BannerWarning {
+  LegacyInspectorWarningMessage({required super.screenId})
+    : super(
+        key: buildKey(screenId),
+        buildTextSpans: (context) => [
+          const TextSpan(
+            text:
+                'The legacy inspector will be removed in a future release. '
+                'Please enable the new inspector in the inspector settings. '
+                'If there is an issue preventing you from using the new '
+                'inspector, please file a ',
+          ),
+          GaLinkTextSpan(
+            link: const GaLink(
+              display: 'bug',
+              url: 'https://github.com/flutter/devtools/issues/new',
+            ),
+            context: context,
+            style: Theme.of(context).linkTextStyle,
+          ),
+          const TextSpan(text: '.'),
+        ],
+      );
+
+  static Key buildKey(String screenId) =>
+      Key('LegacyInspectorWarningMessage - $screenId');
+}
+
 void maybePushDebugModePerformanceMessage(String screenId) {
   if (offlineDataController.showingOfflineData.value) return;
   if (serviceConnection.serviceManager.connectedApp?.isDebugFlutterAppNow ??
@@ -549,6 +577,10 @@
   );
 }
 
+void pushLegacyInspectorWarning(String screenId) {
+  bannerMessages.addMessage(LegacyInspectorWarningMessage(screenId: screenId));
+}
+
 extension BannerMessageThemeExtension on ThemeData {
   TextStyle get warningMessageLinkStyle => regularTextStyle.copyWith(
     decoration: TextDecoration.underline,
diff --git a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md
index 9831e18..c691a04 100644
--- a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md
+++ b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md
@@ -19,7 +19,8 @@
 
 ## Inspector updates
 
-TODO: Remove this section if there are not any general updates.
+- Added a warning banner that the legacy inspector will be removed in a future
+  release. - [#9572](https://github.com/flutter/devtools/pull/9572)
 
 ## Performance updates
 
diff --git a/packages/devtools_app/test/screens/inspector/inspector_integration_test.dart b/packages/devtools_app/test/screens/inspector/inspector_integration_test.dart
index 013ec07..659959a 100644
--- a/packages/devtools_app/test/screens/inspector/inspector_integration_test.dart
+++ b/packages/devtools_app/test/screens/inspector/inspector_integration_test.dart
@@ -3,6 +3,7 @@
 // found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
 
 import 'package:devtools_app/devtools_app.dart';
+import 'package:devtools_app_shared/utils.dart';
 import 'package:devtools_test/helpers.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_test/flutter_test.dart';
@@ -37,6 +38,13 @@
     }
   }
 
+  setUp(() async {
+    await env.setupEnvironment();
+    setGlobal(BannerMessagesController, BannerMessagesController());
+    // Ensure the legacy inspector is enabled:
+    preferences.inspector.setLegacyInspectorEnabled(true);
+  });
+
   group('screenshot tests', () {
     setUpAll(() {
       env = FlutterTestEnvironment(
@@ -45,12 +53,6 @@
       env.afterEverySetup = resetInspectorSelection;
     });
 
-    setUp(() async {
-      await env.setupEnvironment();
-      // Ensure the legacy inspector is enabled:
-      preferences.inspector.setLegacyInspectorEnabled(true);
-    });
-
     tearDownAll(() async {
       await env.tearDownEnvironment(force: true);
     });
diff --git a/packages/devtools_app/test/screens/inspector/inspector_screen_test.dart b/packages/devtools_app/test/screens/inspector/inspector_screen_test.dart
index 7dbc36f..0a09554 100644
--- a/packages/devtools_app/test/screens/inspector/inspector_screen_test.dart
+++ b/packages/devtools_app/test/screens/inspector/inspector_screen_test.dart
@@ -57,6 +57,7 @@
     setGlobal(PreferencesController, PreferencesController());
     setGlobal(Storage, FlutterTestStorage());
     setGlobal(NotificationService, NotificationService());
+    setGlobal(BannerMessagesController, BannerMessagesController());
     fakeServiceConnection.consoleService.ensureServiceInitialized();
     // Enable the legacy inspector:
     preferences.inspector.setLegacyInspectorEnabled(true);
diff --git a/packages/devtools_app/test/screens/inspector_v2/inspector_integration_test.dart b/packages/devtools_app/test/screens/inspector_v2/inspector_integration_test.dart
index 6d4e0cb..c9f902f 100644
--- a/packages/devtools_app/test/screens/inspector_v2/inspector_integration_test.dart
+++ b/packages/devtools_app/test/screens/inspector_v2/inspector_integration_test.dart
@@ -18,6 +18,7 @@
 import 'package:devtools_app/src/screens/inspector_v2/layout_explorer/ui/utils.dart';
 import 'package:devtools_app/src/screens/inspector_v2/widget_properties/properties_view.dart';
 import 'package:devtools_app_shared/ui.dart';
+import 'package:devtools_app_shared/utils.dart';
 import 'package:devtools_test/helpers.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_test/flutter_test.dart';
@@ -64,6 +65,7 @@
     await env.setupEnvironment();
     // Enable the V2 inspector:
     preferences.inspector.setLegacyInspectorEnabled(false);
+    setGlobal(BannerMessagesController, BannerMessagesController());
   });
 
   tearDown(() async {