Disable single character mode in the terminal when exiting flutter_tools (#146534)

diff --git a/packages/flutter_tools/lib/executable.dart b/packages/flutter_tools/lib/executable.dart
index 2690759..0938e64 100644
--- a/packages/flutter_tools/lib/executable.dart
+++ b/packages/flutter_tools/lib/executable.dart
@@ -136,6 +136,7 @@
           // So that we don't animate anything before calling applyFeatureFlags, default
           // the animations to disabled in real apps.
           defaultCliAnimationEnabled: false,
+          shutdownHooks: globals.shutdownHooks,
         );
         // runner.run calls "terminal.applyFeatureFlags()"
       },
diff --git a/packages/flutter_tools/lib/src/base/terminal.dart b/packages/flutter_tools/lib/src/base/terminal.dart
index 7443bd0..4edce49 100644
--- a/packages/flutter_tools/lib/src/base/terminal.dart
+++ b/packages/flutter_tools/lib/src/base/terminal.dart
@@ -7,6 +7,7 @@
 import 'io.dart' as io;
 import 'logger.dart';
 import 'platform.dart';
+import 'process.dart';
 
 enum TerminalColor {
   red,
@@ -164,11 +165,14 @@
     required Platform platform,
     DateTime? now, // Time used to determine preferredStyle. Defaults to 0001-01-01 00:00.
     bool defaultCliAnimationEnabled = true,
+    ShutdownHooks? shutdownHooks,
   })
     : _stdio = stdio,
       _platform = platform,
       _now = now ?? DateTime(1),
-      _isCliAnimationEnabled = defaultCliAnimationEnabled;
+      _isCliAnimationEnabled = defaultCliAnimationEnabled {
+    shutdownHooks?.addShutdownHook(() { singleCharMode = false; });
+  }
 
   final io.Stdio _stdio;
   final Platform _platform;
@@ -319,7 +323,7 @@
       return false;
     }
     final io.Stdin stdin = _stdio.stdin as io.Stdin;
-    return stdin.lineMode && stdin.echoMode;
+    return !stdin.lineMode && !stdin.echoMode;
   }
   @override
   set singleCharMode(bool value) {
diff --git a/packages/flutter_tools/lib/src/globals.dart b/packages/flutter_tools/lib/src/globals.dart
index bb39d9b..7dd0089 100644
--- a/packages/flutter_tools/lib/src/globals.dart
+++ b/packages/flutter_tools/lib/src/globals.dart
@@ -243,6 +243,7 @@
   stdio: stdio,
   platform: platform,
   now: DateTime.now(),
+  shutdownHooks: shutdownHooks,
 );
 
 /// The global Stdio wrapper.
diff --git a/packages/flutter_tools/test/general.shard/base/terminal_test.dart b/packages/flutter_tools/test/general.shard/base/terminal_test.dart
index 5810a58..0e921de 100644
--- a/packages/flutter_tools/test/general.shard/base/terminal_test.dart
+++ b/packages/flutter_tools/test/general.shard/base/terminal_test.dart
@@ -5,6 +5,7 @@
 import 'package:flutter_tools/src/base/io.dart';
 import 'package:flutter_tools/src/base/logger.dart';
 import 'package:flutter_tools/src/base/platform.dart';
+import 'package:flutter_tools/src/base/process.dart';
 import 'package:flutter_tools/src/base/terminal.dart';
 import 'package:test/fake.dart';
 
@@ -264,6 +265,18 @@
     );
     terminal.singleCharMode = true;
   });
+
+  testWithoutContext('singleCharMode is reset by shutdown hook', () {
+    final ShutdownHooks shutdownHooks = ShutdownHooks();
+    final FakeStdio stdio = FakeStdio();
+    final AnsiTerminal terminal = AnsiTerminal(stdio: stdio, platform: const LocalPlatform(), shutdownHooks: shutdownHooks);
+    stdio.stdinHasTerminal = true;
+    stdio._stdin = FakeStdin();
+
+    terminal.singleCharMode = true;
+    shutdownHooks.runShutdownHooks(BufferLogger.test());
+    expect(terminal.singleCharMode, false);
+  });
 }
 
 late Stream<String> mockStdInStream;