[null-safety] update tests and tool auto-detection for null safe dart (#69405)

Disable null safety auto-detection for the web
diff --git a/dev/bots/test.dart b/dev/bots/test.dart
index 1e240c3..e41a6e1 100644
--- a/dev/bots/test.dart
+++ b/dev/bots/test.dart
@@ -912,6 +912,7 @@
       '--driver=test_driver/transitions_perf_e2e_test.dart',
       '--target=test_driver/transitions_perf_e2e.dart',
       '--browser-name=chrome',
+      '--no-sound-null-safety',
       '-d',
       'web-server',
       '--$buildMode',
diff --git a/dev/integration_tests/flutter_gallery/test_driver/run_demos.dart b/dev/integration_tests/flutter_gallery/test_driver/run_demos.dart
index 2df9fab..5f465fc 100644
--- a/dev/integration_tests/flutter_gallery/test_driver/run_demos.dart
+++ b/dev/integration_tests/flutter_gallery/test_driver/run_demos.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.
 
+// @dart = 2.9
 import 'dart:ui';
 
 import 'package:flutter/cupertino.dart';
diff --git a/dev/integration_tests/flutter_gallery/test_driver/scroll_perf.dart b/dev/integration_tests/flutter_gallery/test_driver/scroll_perf.dart
index a82bc68..4440370 100644
--- a/dev/integration_tests/flutter_gallery/test_driver/scroll_perf.dart
+++ b/dev/integration_tests/flutter_gallery/test_driver/scroll_perf.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.
 
+// @dart = 2.9
 import 'package:flutter_driver/driver_extension.dart';
 import 'package:flutter_gallery/gallery/app.dart' show GalleryApp;
 import 'package:flutter/material.dart';
diff --git a/dev/integration_tests/flutter_gallery/test_driver/scroll_perf_test.dart b/dev/integration_tests/flutter_gallery/test_driver/scroll_perf_test.dart
index 668db67..9e6c1e2 100644
--- a/dev/integration_tests/flutter_gallery/test_driver/scroll_perf_test.dart
+++ b/dev/integration_tests/flutter_gallery/test_driver/scroll_perf_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.
 
+// @dart = 2.9
 import 'package:flutter_driver/flutter_driver.dart';
 import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
 
diff --git a/dev/integration_tests/flutter_gallery/test_driver/scroll_perf_web.dart b/dev/integration_tests/flutter_gallery/test_driver/scroll_perf_web.dart
index 1df1be8..ffdaed6 100644
--- a/dev/integration_tests/flutter_gallery/test_driver/scroll_perf_web.dart
+++ b/dev/integration_tests/flutter_gallery/test_driver/scroll_perf_web.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.
 
+// @dart = 2.9
 import 'package:flutter_driver/driver_extension.dart';
 import 'package:flutter_gallery/gallery/app.dart' show GalleryApp;
 import 'package:flutter/material.dart';
diff --git a/dev/integration_tests/flutter_gallery/test_driver/scroll_perf_web_test.dart b/dev/integration_tests/flutter_gallery/test_driver/scroll_perf_web_test.dart
index a71ef59..528f334 100644
--- a/dev/integration_tests/flutter_gallery/test_driver/scroll_perf_web_test.dart
+++ b/dev/integration_tests/flutter_gallery/test_driver/scroll_perf_web_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.
 
+// @dart = 2.9
 import 'package:flutter_driver/flutter_driver.dart';
 import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
 
diff --git a/dev/integration_tests/flutter_gallery/test_driver/transitions_perf.dart b/dev/integration_tests/flutter_gallery/test_driver/transitions_perf.dart
index b4e7e64..ae88a38 100644
--- a/dev/integration_tests/flutter_gallery/test_driver/transitions_perf.dart
+++ b/dev/integration_tests/flutter_gallery/test_driver/transitions_perf.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.
 
+// @dart = 2.9
 import 'dart:convert' show JsonEncoder;
 
 import 'package:flutter_driver/driver_extension.dart';
diff --git a/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_e2e.dart b/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_e2e.dart
index d1f6c4f..2125517 100644
--- a/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_e2e.dart
+++ b/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_e2e.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.
 
+// @dart = 2.9
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/widgets.dart';
 import 'package:flutter_test/flutter_test.dart';
diff --git a/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_e2e_test.dart b/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_e2e_test.dart
index d931eff..1d2eeec 100644
--- a/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_e2e_test.dart
+++ b/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_e2e_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.
 
+// @dart = 2.9
 import 'package:integration_test/integration_test_driver.dart' as driver;
 
 Future<void> main() => driver.integrationDriver(
diff --git a/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_e2e_with_semantics.dart b/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_e2e_with_semantics.dart
index 1f26cbd..e30850d 100644
--- a/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_e2e_with_semantics.dart
+++ b/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_e2e_with_semantics.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.
 
+// @dart = 2.9
 import 'transitions_perf_e2e.dart' as transitions_perf;
 
 void main() {
diff --git a/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_hybrid_test.dart b/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_hybrid_test.dart
index dc5ab42..572a03b 100644
--- a/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_hybrid_test.dart
+++ b/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_hybrid_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.
 
+// @dart = 2.9
 import 'transitions_perf_test.dart' as transitions_perf_test;
 
 void main([List<String> args = const <String>[]]) => transitions_perf_test.main(
diff --git a/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_test.dart b/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_test.dart
index 7cf23b0..ea97a6f 100644
--- a/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_test.dart
+++ b/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_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.
 
+// @dart = 2.9
 import 'dart:convert' show JsonEncoder, json;
 
 import 'package:file/file.dart';
diff --git a/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_with_semantics_test.dart b/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_with_semantics_test.dart
index eaa0ca2..40c924b 100644
--- a/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_with_semantics_test.dart
+++ b/dev/integration_tests/flutter_gallery/test_driver/transitions_perf_with_semantics_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.
 
+// @dart = 2.9
 import 'transitions_perf_test.dart' as transitions_perf_test;
 
 void main() {
diff --git a/dev/integration_tests/flutter_gallery/test_memory/back_button.dart b/dev/integration_tests/flutter_gallery/test_memory/back_button.dart
index 140a45a..79914614 100644
--- a/dev/integration_tests/flutter_gallery/test_memory/back_button.dart
+++ b/dev/integration_tests/flutter_gallery/test_memory/back_button.dart
@@ -4,6 +4,7 @@
 
 // See //dev/devicelab/bin/tasks/flutter_gallery__memory_nav.dart
 
+// @dart = 2.9
 import 'package:flutter/material.dart';
 import 'package:flutter/scheduler.dart';
 import 'package:flutter_gallery/gallery/app.dart' show GalleryApp;
diff --git a/dev/integration_tests/flutter_gallery/test_memory/image_cache_memory.dart b/dev/integration_tests/flutter_gallery/test_memory/image_cache_memory.dart
index df8eb3b..8ef468f 100644
--- a/dev/integration_tests/flutter_gallery/test_memory/image_cache_memory.dart
+++ b/dev/integration_tests/flutter_gallery/test_memory/image_cache_memory.dart
@@ -4,6 +4,7 @@
 
 // See //dev/devicelab/bin/tasks/flutter_gallery__image_cache_memory.dart
 
+// @dart = 2.9
 import 'package:flutter/widgets.dart';
 import 'package:flutter/scheduler.dart';
 import 'package:flutter_test/flutter_test.dart';
diff --git a/dev/integration_tests/flutter_gallery/test_memory/memory_nav.dart b/dev/integration_tests/flutter_gallery/test_memory/memory_nav.dart
index 5bfd47c..df20344 100644
--- a/dev/integration_tests/flutter_gallery/test_memory/memory_nav.dart
+++ b/dev/integration_tests/flutter_gallery/test_memory/memory_nav.dart
@@ -4,6 +4,7 @@
 
 // See //dev/devicelab/bin/tasks/flutter_gallery__memory_nav.dart
 
+// @dart = 2.9
 import 'dart:async';
 
 import 'package:flutter/material.dart';
diff --git a/dev/integration_tests/web_e2e_tests/test_driver/text_editing_integration.dart b/dev/integration_tests/web_e2e_tests/test_driver/text_editing_integration.dart
index 3c6633d..4524899 100644
--- a/dev/integration_tests/web_e2e_tests/test_driver/text_editing_integration.dart
+++ b/dev/integration_tests/web_e2e_tests/test_driver/text_editing_integration.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.
 
+// @dart = 2.9
 import 'dart:html';
 import 'dart:js_util' as js_util;
 import 'package:flutter/gestures.dart';
diff --git a/dev/integration_tests/web_e2e_tests/test_driver/text_editing_integration_test.dart b/dev/integration_tests/web_e2e_tests/test_driver/text_editing_integration_test.dart
index b2d2a17..94f9938 100644
--- a/dev/integration_tests/web_e2e_tests/test_driver/text_editing_integration_test.dart
+++ b/dev/integration_tests/web_e2e_tests/test_driver/text_editing_integration_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.
 
+// @dart = 2.9
 import 'package:integration_test/integration_test_driver.dart' as test;
 
 Future<void> main() async => test.integrationDriver();
diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart
index 5dcc730..e01c04d 100644
--- a/packages/flutter_tools/lib/src/resident_runner.dart
+++ b/packages/flutter_tools/lib/src/resident_runner.dart
@@ -97,12 +97,17 @@
       if (buildInfo.nullSafetyMode == NullSafetyMode.unsound) {
         platformDillArtifact = Artifact.webPlatformKernelDill;
         extraFrontEndOptions = buildInfo.extraFrontEndOptions;
-      } else {
+      } else if (buildInfo.nullSafetyMode == NullSafetyMode.sound) {
         platformDillArtifact = Artifact.webPlatformSoundKernelDill;
-        extraFrontEndOptions = <String>[
-          ...?buildInfo?.extraFrontEndOptions,
-          if (!(buildInfo?.extraFrontEndOptions?.contains('--sound-null-safety') ?? false))
-            '--sound-null-safety'
+        extraFrontEndOptions =  buildInfo.extraFrontEndOptions;
+      } else {
+        // TODO(jonahwilliams): null-safe auto detection does not currently
+        // work on the web. Always opt out of null safety if it was not
+        // specifically requested.
+        platformDillArtifact = Artifact.webPlatformKernelDill;
+        extraFrontEndOptions =  <String>[
+          ...?buildInfo.extraFrontEndOptions,
+          '--no-sound-null-safety',
         ];
       }
 
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart
index cd7eea5..1430d67 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart
@@ -585,7 +585,7 @@
         'Flutter mobile & desktop applications will attempt to run at the null safety '
         'level of their entrypoint library (usually lib/main.dart). Flutter web '
         'applications will default to sound null-safety, unless specifically configured.',
-      defaultsTo: null,
+      defaultsTo: true,
       hide: hide,
     );
     argParser.addFlag(FlutterOptions.kNullAssertions,
@@ -783,18 +783,17 @@
 
     NullSafetyMode nullSafetyMode = NullSafetyMode.unsound;
     if (argParser.options.containsKey(FlutterOptions.kNullSafety)) {
-      final bool nullSafety = boolArg(FlutterOptions.kNullSafety);
       // Explicitly check for `true` and `false` so that `null` results in not
       // passing a flag. This will use the automatically detected null-safety
       // value based on the entrypoint
-      if (nullSafety == true) {
+      if (!argResults.wasParsed(FlutterOptions.kNullSafety)) {
+        nullSafetyMode = NullSafetyMode.autodetect;
+      } else if (boolArg(FlutterOptions.kNullSafety)) {
         nullSafetyMode = NullSafetyMode.sound;
         extraFrontEndOptions.add('--sound-null-safety');
-      } else if (nullSafety == false) {
+      } else {
         nullSafetyMode = NullSafetyMode.unsound;
         extraFrontEndOptions.add('--no-sound-null-safety');
-      } else if (extraFrontEndOptions.contains('--enable-experiment=non-nullable')) {
-        nullSafetyMode = NullSafetyMode.autodetect;
       }
     }
 
diff --git a/packages/flutter_tools/test/general.shard/resident_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_runner_test.dart
index e5dfd8c..212d31e 100644
--- a/packages/flutter_tools/test/general.shard/resident_runner_test.dart
+++ b/packages/flutter_tools/test/general.shard/resident_runner_test.dart
@@ -2517,7 +2517,7 @@
     Artifacts: () => Artifacts.test(),
     FileSystem: () => MemoryFileSystem.test(),
     ProcessManager: () => FakeProcessManager.any(),
-  });
+  }, skip: true); // TODO(jonahwilliams): null safe autodetection does not work on the web.
 
   testUsingContext('FlutterDevice passes flutter-widget-cache flag when feature is enabled', () async {
     fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);