1.20.0-7.3.pre beta cherrypicks (#62444)

* Update engine hash to 1.20.0-7.3.pre

* [flutter_tools] revert dart format changes (#61760)

* Allow hyphens in iOS UDIDs (#62225)

Co-authored-by: Jonah Williams <jonahwilliams@google.com>
Co-authored-by: Jenn Magder <magder@google.com>
diff --git a/bin/internal/engine.version b/bin/internal/engine.version
index 5573084..3d725e9 100644
--- a/bin/internal/engine.version
+++ b/bin/internal/engine.version
@@ -1 +1 @@
-60b269d898cbe0be27e9b9ba9d21eae97b887ab6
+ac95267aef5175b3f6c3387d502070c68f588ad5
diff --git a/packages/flutter_tools/lib/src/commands/format.dart b/packages/flutter_tools/lib/src/commands/format.dart
index 6778ca1..35bd514 100644
--- a/packages/flutter_tools/lib/src/commands/format.dart
+++ b/packages/flutter_tools/lib/src/commands/format.dart
@@ -4,8 +4,6 @@
 
 import 'dart:async';
 
-import 'package:args/args.dart';
-
 import '../artifacts.dart';
 import '../base/common.dart';
 import '../base/process.dart';
@@ -13,9 +11,30 @@
 import '../runner/flutter_command.dart';
 
 class FormatCommand extends FlutterCommand {
-  @override
-  ArgParser get argParser => _argParser;
-  final ArgParser _argParser = ArgParser.allowAnything();
+  FormatCommand() {
+    argParser.addFlag('dry-run',
+      abbr: 'n',
+      help: 'Show which files would be modified but make no changes.',
+      defaultsTo: false,
+      negatable: false,
+    );
+    argParser.addFlag('set-exit-if-changed',
+      help: 'Return exit code 1 if there are any formatting changes.',
+      defaultsTo: false,
+      negatable: false,
+    );
+    argParser.addFlag('machine',
+      abbr: 'm',
+      help: 'Produce machine-readable JSON output.',
+      defaultsTo: false,
+      negatable: false,
+    );
+    argParser.addOption('line-length',
+      abbr: 'l',
+      help: 'Wrap lines longer than this length. Defaults to 80 characters.',
+      defaultsTo: '80',
+    );
+  }
 
   @override
   final String name = 'format';
@@ -30,21 +49,36 @@
   String get invocation => '${runner.executableName} $name <one or more paths>';
 
   @override
-  bool get shouldUpdateCache => false;
-
-  @override
   Future<FlutterCommandResult> runCommand() async {
+    if (argResults.rest.isEmpty) {
+      throwToolExit(
+        'No files specified to be formatted.\n'
+        '\n'
+        'To format all files in the current directory tree:\n'
+        '${runner.executableName} $name .\n'
+        '\n'
+        '$usage'
+      );
+    }
+
+    final String dartSdk = globals.artifacts.getArtifactPath(Artifact.engineDartSdkPath);
     final String dartBinary = globals.artifacts.getArtifactPath(Artifact.engineDartBinary);
     final List<String> command = <String>[
       dartBinary,
-      'format',
+      globals.fs.path.join(dartSdk, 'bin', 'snapshots', 'dartfmt.dart.snapshot'),
+      if (boolArg('dry-run')) '-n',
+      if (boolArg('machine')) '-m',
+      if (argResults['line-length'] != null) '-l ${argResults['line-length']}',
+      if (!boolArg('dry-run') && !boolArg('machine')) '-w',
+      if (boolArg('set-exit-if-changed')) '--set-exit-if-changed',
       ...argResults.rest,
     ];
 
     final int result = await processUtils.stream(command);
     if (result != 0) {
-      throwToolExit('', exitCode: result);
+      throwToolExit('Formatting failed: $result', exitCode: result);
     }
+
     return FlutterCommandResult.success();
   }
 }
diff --git a/packages/flutter_tools/lib/src/macos/xcode.dart b/packages/flutter_tools/lib/src/macos/xcode.dart
index 81a430c..9ced7d6 100644
--- a/packages/flutter_tools/lib/src/macos/xcode.dart
+++ b/packages/flutter_tools/lib/src/macos/xcode.dart
@@ -326,8 +326,9 @@
   }
 
   // Attach: d83d5bc53967baa0ee18626ba87b6254b2ab5418
+  // Attach: 00008027-00192736010F802E
   // Detach: d83d5bc53967baa0ee18626ba87b6254b2ab5418
-  final RegExp _observationIdentifierPattern = RegExp(r'^(\w*): (\w*)$');
+  final RegExp _observationIdentifierPattern = RegExp(r'^(\w*): ([\w-]*)$');
 
   Future<void> _startObservingTetheredIOSDevices() async {
     try {
@@ -359,6 +360,7 @@
         //
         // Listening for all devices, on both interfaces.
         // Attach: d83d5bc53967baa0ee18626ba87b6254b2ab5418
+        // Attach: 00008027-00192736010F802E
         // Detach: d83d5bc53967baa0ee18626ba87b6254b2ab5418
         // Attach: d83d5bc53967baa0ee18626ba87b6254b2ab5418
         final RegExpMatch match = _observationIdentifierPattern.firstMatch(line);
diff --git a/packages/flutter_tools/test/commands.shard/permeable/format_test.dart b/packages/flutter_tools/test/commands.shard/permeable/format_test.dart
new file mode 100644
index 0000000..b591275
--- /dev/null
+++ b/packages/flutter_tools/test/commands.shard/permeable/format_test.dart
@@ -0,0 +1,104 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:args/command_runner.dart';
+import 'package:flutter_tools/src/base/file_system.dart';
+import 'package:flutter_tools/src/cache.dart';
+import 'package:flutter_tools/src/commands/format.dart';
+import 'package:flutter_tools/src/globals.dart' as globals;
+
+import '../../src/common.dart';
+import '../../src/context.dart';
+
+void main() {
+  group('format', () {
+    Directory tempDir;
+
+    setUp(() {
+      Cache.disableLocking();
+      tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_tools_format_test.');
+    });
+
+    tearDown(() {
+      tryToDelete(tempDir);
+    });
+
+    testUsingContext('a file', () async {
+      final String projectPath = await createProject(tempDir);
+
+      final File srcFile = globals.fs.file(globals.fs.path.join(projectPath, 'lib', 'main.dart'));
+      final String original = srcFile.readAsStringSync();
+      srcFile.writeAsStringSync(original.replaceFirst('main()', 'main(  )'));
+
+      final FormatCommand command = FormatCommand();
+      final CommandRunner<void> runner = createTestCommandRunner(command);
+      await runner.run(<String>['format', srcFile.path]);
+
+      final String formatted = srcFile.readAsStringSync();
+      expect(formatted, original);
+    });
+
+    testUsingContext('dry-run', () async {
+      final String projectPath = await createProject(tempDir);
+
+      final File srcFile = globals.fs.file(
+          globals.fs.path.join(projectPath, 'lib', 'main.dart'));
+      final String nonFormatted = srcFile.readAsStringSync().replaceFirst(
+          'main()', 'main(  )');
+      srcFile.writeAsStringSync(nonFormatted);
+
+      final FormatCommand command = FormatCommand();
+      final CommandRunner<void> runner = createTestCommandRunner(command);
+      await runner.run(<String>['format', '--dry-run', srcFile.path]);
+
+      final String shouldNotFormatted = srcFile.readAsStringSync();
+      expect(shouldNotFormatted, nonFormatted);
+    });
+
+    testUsingContext('dry-run with set-exit-if-changed', () async {
+      final String projectPath = await createProject(tempDir);
+
+      final File srcFile = globals.fs.file(
+          globals.fs.path.join(projectPath, 'lib', 'main.dart'));
+      final String nonFormatted = srcFile.readAsStringSync().replaceFirst(
+          'main()', 'main(  )');
+      srcFile.writeAsStringSync(nonFormatted);
+
+      final FormatCommand command = FormatCommand();
+      final CommandRunner<void> runner = createTestCommandRunner(command);
+
+      expect(runner.run(<String>[
+        'format', '--dry-run', '--set-exit-if-changed', srcFile.path,
+      ]), throwsException);
+
+      final String shouldNotFormatted = srcFile.readAsStringSync();
+      expect(shouldNotFormatted, nonFormatted);
+    });
+
+    testUsingContext('line-length', () async {
+      const int lineLengthShort = 50;
+      const int lineLengthLong = 120;
+      final String projectPath = await createProject(tempDir);
+
+      final File srcFile = globals.fs.file(
+          globals.fs.path.join(projectPath, 'lib', 'main.dart'));
+      final String nonFormatted = srcFile.readAsStringSync();
+      srcFile.writeAsStringSync(
+          nonFormatted.replaceFirst('main()',
+              'main(anArgument1, anArgument2, anArgument3, anArgument4, anArgument5)'));
+
+      final String nonFormattedWithLongLine = srcFile.readAsStringSync();
+      final FormatCommand command = FormatCommand();
+      final CommandRunner<void> runner = createTestCommandRunner(command);
+
+      await runner.run(<String>['format', '--line-length', '$lineLengthLong', srcFile.path]);
+      final String notFormatted = srcFile.readAsStringSync();
+      expect(nonFormattedWithLongLine, notFormatted);
+
+      await runner.run(<String>['format', '--line-length', '$lineLengthShort', srcFile.path]);
+      final String shouldFormatted = srcFile.readAsStringSync();
+      expect(nonFormattedWithLongLine, isNot(shouldFormatted));
+    });
+  });
+}
diff --git a/packages/flutter_tools/test/general.shard/commands/format_test.dart b/packages/flutter_tools/test/general.shard/commands/format_test.dart
deleted file mode 100644
index c584bad..0000000
--- a/packages/flutter_tools/test/general.shard/commands/format_test.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2014 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:args/command_runner.dart';
-import 'package:file/memory.dart';
-import 'package:flutter_tools/src/artifacts.dart';
-import 'package:flutter_tools/src/base/file_system.dart';
-import 'package:flutter_tools/src/commands/format.dart';
-import 'package:flutter_tools/src/globals.dart' as globals;
-
-import '../../src/common.dart';
-import '../../src/context.dart';
-
-void main() {
-  testUsingContext('flutter format forward all arguments to dart format and '
-    'prints deprecation warning', () async {
-    final CommandRunner<void> runner = CommandRunner<void>('flutter', 'test')
-      ..addCommand(FormatCommand());
-    await runner.run(<String>['format', 'a', 'b', 'c']);
-
-    expect((globals.processManager as FakeProcessManager).hasRemainingExpectations, false);
-  }, overrides: <Type, Generator>{
-    FileSystem: () => MemoryFileSystem.test(),
-    ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
-      FakeCommand(
-        command: <String>[
-          globals.artifacts.getArtifactPath(Artifact.engineDartBinary),
-          'format',
-          'a',
-          'b',
-          'c',
-        ],
-      )
-    ])
-  });
-}
diff --git a/packages/flutter_tools/test/general.shard/ios/devices_test.dart b/packages/flutter_tools/test/general.shard/ios/devices_test.dart
index f91f7ac..e0d8fc2 100644
--- a/packages/flutter_tools/test/general.shard/ios/devices_test.dart
+++ b/packages/flutter_tools/test/general.shard/ios/devices_test.dart
@@ -355,8 +355,8 @@
       );
 
       device2 = IOSDevice(
-        '43ad2fda7991b34fe1acbda82f9e2fd3d6ddc9f7',
-        name: 'iPhone 6s',
+        '00008027-00192736010F802E',
+        name: 'iPad Pro',
         sdkVersion: '13.3',
         cpuArchitecture: DarwinArch.arm64,
         artifacts: mockArtifacts,
diff --git a/packages/flutter_tools/test/general.shard/macos/xcode_test.dart b/packages/flutter_tools/test/general.shard/macos/xcode_test.dart
index 4f9008c..3ca7bf3 100644
--- a/packages/flutter_tools/test/general.shard/macos/xcode_test.dart
+++ b/packages/flutter_tools/test/general.shard/macos/xcode_test.dart
@@ -381,29 +381,37 @@
               'observe',
               '--both',
             ], stdout: 'Attach: d83d5bc53967baa0ee18626ba87b6254b2ab5418\n'
-            'Detach: d83d5bc53967baa0ee18626ba87b6254b2ab5418',
+              'Attach: 00008027-00192736010F802E\n'
+              'Detach: d83d5bc53967baa0ee18626ba87b6254b2ab5418',
             stderr: 'Some error',
           ));
 
-          final Completer<void> attach = Completer<void>();
-          final Completer<void> detach = Completer<void>();
+          final Completer<void> attach1 = Completer<void>();
+          final Completer<void> attach2 = Completer<void>();
+          final Completer<void> detach1 = Completer<void>();
 
           // Attach: d83d5bc53967baa0ee18626ba87b6254b2ab5418
+          // Attach: 00008027-00192736010F802E
           // Detach: d83d5bc53967baa0ee18626ba87b6254b2ab5418
           xcdevice.observedDeviceEvents().listen((Map<XCDeviceEvent, String> event) {
             expect(event.length, 1);
             if (event.containsKey(XCDeviceEvent.attach)) {
-              expect(event[XCDeviceEvent.attach], 'd83d5bc53967baa0ee18626ba87b6254b2ab5418');
-              attach.complete();
+              if (event[XCDeviceEvent.attach] == 'd83d5bc53967baa0ee18626ba87b6254b2ab5418') {
+                attach1.complete();
+              } else
+              if (event[XCDeviceEvent.attach] == '00008027-00192736010F802E') {
+                attach2.complete();
+              }
             } else if (event.containsKey(XCDeviceEvent.detach)) {
               expect(event[XCDeviceEvent.detach], 'd83d5bc53967baa0ee18626ba87b6254b2ab5418');
-              detach.complete();
+              detach1.complete();
             } else {
               fail('Unexpected event');
             }
           });
-          await attach.future;
-          await detach.future;
+          await attach1.future;
+          await attach2.future;
+          await detach1.future;
           expect(logger.traceText, contains('xcdevice observe error: Some error'));
         });
       });
@@ -444,7 +452,7 @@
     "available" : true,
     "platform" : "com.apple.platform.iphoneos",
     "modelCode" : "iPhone8,1",
-    "identifier" : "d83d5bc53967baa0ee18626ba87b6254b2ab5418",
+    "identifier" : "00008027-00192736010F802E",
     "architecture" : "arm64",
     "modelName" : "iPhone 6s",
     "name" : "An iPhone (Space Gray)"
@@ -523,7 +531,7 @@
           ));
           final List<IOSDevice> devices = await xcdevice.getAvailableIOSDevices();
           expect(devices, hasLength(3));
-          expect(devices[0].id, 'd83d5bc53967baa0ee18626ba87b6254b2ab5418');
+          expect(devices[0].id, '00008027-00192736010F802E');
           expect(devices[0].name, 'An iPhone (Space Gray)');
           expect(await devices[0].sdkNameAndVersion, 'iOS 13.3');
           expect(devices[0].cpuArchitecture, DarwinArch.arm64);