Step 1 of 3: Add opt-in fixing Dialog border radius to match Material Spec (#56084)

diff --git a/packages/flutter/lib/src/material/dialog.dart b/packages/flutter/lib/src/material/dialog.dart
index 3076688..b657e93 100644
--- a/packages/flutter/lib/src/material/dialog.dart
+++ b/packages/flutter/lib/src/material/dialog.dart
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// TODO(shihaohong): remove ignoring deprecated member use analysis
-// when AlertDialog.scrollable parameter is removed. See
-// https://flutter.dev/go/scrollable-alert-dialog for more details.
+// TODO(shihaohong-Piinks): remove ignoring deprecated member use analysis
+//   * when AlertDialog.scrollable parameter is removed. See
+//     https://flutter.dev/go/scrollable-alert-dialog for more details.
+//   * when Dialog.useMaterialBorderRadius parameter is removed.
 // ignore_for_file: deprecated_member_use_from_same_package
 
 import 'dart:async';
@@ -55,7 +56,9 @@
     this.clipBehavior = Clip.none,
     this.shape,
     this.child,
+    bool useMaterialBorderRadius,
   }) : assert(clipBehavior != null),
+       useMaterialBorderRadius = useMaterialBorderRadius ?? false,
        super(key: key);
 
   /// {@template flutter.material.dialog.backgroundColor}
@@ -117,7 +120,8 @@
   ///
   /// Defines the dialog's [Material.shape].
   ///
-  /// The default shape is a [RoundedRectangleBorder] with a radius of 2.0.
+  /// The default shape is a [RoundedRectangleBorder] with a radius of 2.0
+  /// (temporarily, set [useMaterialBorderRadius] to match Material guidelines).
   /// {@endtemplate}
   final ShapeBorder shape;
 
@@ -126,8 +130,19 @@
   /// {@macro flutter.widgets.child}
   final Widget child;
 
-  // TODO(johnsonmh): Update default dialog border radius to 4.0 to match material spec.
+  /// Indicates whether the [Dialog.shape]'s default [RoundedRectangleBorder]
+  /// should have a radius of 4.0 pixels to match Material Design, or use the
+  /// prior default of 2.0 pixels.
+  @Deprecated(
+    'Set useMaterialBorderRadius to `true`. This parameter will be removed and '
+    'was introduced to migrate Dialog to the correct border radius by default. '
+    'This feature was deprecated after v1.18.0.'
+  )
+  final bool useMaterialBorderRadius;
+
   static const RoundedRectangleBorder _defaultDialogShape =
+    RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0)));
+  static const RoundedRectangleBorder _oldDefaultDialogShape =
     RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.0)));
   static const double _defaultElevation = 24.0;
 
@@ -151,7 +166,11 @@
             child: Material(
               color: backgroundColor ?? dialogTheme.backgroundColor ?? Theme.of(context).dialogBackgroundColor,
               elevation: elevation ?? dialogTheme.elevation ?? _defaultElevation,
-              shape: shape ?? dialogTheme.shape ?? _defaultDialogShape,
+              shape: shape ?? dialogTheme.shape ?? (
+                useMaterialBorderRadius ?
+                  _defaultDialogShape :
+                  _oldDefaultDialogShape
+              ),
               type: MaterialType.card,
               clipBehavior: clipBehavior,
               child: child,
@@ -260,8 +279,10 @@
     this.clipBehavior = Clip.none,
     this.shape,
     this.scrollable = false,
+    bool useMaterialBorderRadius,
   }) : assert(contentPadding != null),
        assert(clipBehavior != null),
+       useMaterialBorderRadius = useMaterialBorderRadius ?? false,
        super(key: key);
 
   /// The (optional) title of the dialog is displayed in a large font at the top
@@ -449,6 +470,16 @@
   )
   final bool scrollable;
 
+  /// Indicates whether the [Dialog.shape]'s default [RoundedRectangleBorder]
+  /// should have a radius of 4.0 pixels to match Material Design, or use the
+  /// prior default of 2.0 pixels.
+  @Deprecated(
+    'Set useMaterialBorderRadius to `true`. This parameter will be removed and '
+    'was introduced to migrate Dialog to the correct border radius by default. '
+    'This feature was deprecated after v1.18.0.'
+  )
+  final bool useMaterialBorderRadius;
+
   @override
   Widget build(BuildContext context) {
     assert(debugCheckHasMaterialLocalizations(context));
@@ -560,6 +591,7 @@
       clipBehavior: clipBehavior,
       shape: shape,
       child: dialogChild,
+      useMaterialBorderRadius: useMaterialBorderRadius,
     );
   }
 }
@@ -719,8 +751,10 @@
     this.elevation,
     this.semanticLabel,
     this.shape,
+    bool useMaterialBorderRadius,
   }) : assert(titlePadding != null),
        assert(contentPadding != null),
+       useMaterialBorderRadius = useMaterialBorderRadius ?? false,
        super(key: key);
 
   /// The (optional) title of the dialog is displayed in a large font at the top
@@ -789,6 +823,16 @@
   /// {@macro flutter.material.dialog.shape}
   final ShapeBorder shape;
 
+  /// Indicates whether the [Dialog.shape]'s default [RoundedRectangleBorder]
+  /// should have a radius of 4.0 pixels to match Material Design, or use the
+  /// prior default of 2.0 pixels.
+  @Deprecated(
+    'Set useMaterialBorderRadius to `true`. This parameter will be removed and '
+    'was introduced to migrate Dialog to the correct border radius by default. '
+    'This feature was deprecated after v1.18.0.'
+  )
+  final bool useMaterialBorderRadius;
+
   @override
   Widget build(BuildContext context) {
     assert(debugCheckHasMaterialLocalizations(context));
@@ -848,6 +892,7 @@
       elevation: elevation,
       shape: shape,
       child: dialogChild,
+      useMaterialBorderRadius: useMaterialBorderRadius,
     );
   }
 }
diff --git a/packages/flutter/lib/src/material/pickers/date_picker_dialog.dart b/packages/flutter/lib/src/material/pickers/date_picker_dialog.dart
index 4ce0992..85c38ca 100644
--- a/packages/flutter/lib/src/material/pickers/date_picker_dialog.dart
+++ b/packages/flutter/lib/src/material/pickers/date_picker_dialog.dart
@@ -503,6 +503,7 @@
         ),
       ),
       insetPadding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0),
+      // TODO(Piinks): remove once border radius migration is complete
       // The default dialog shape is radius 2 rounded rect, but the spec has
       // been updated to 4, so we will use that here for the Date Picker, but
       // only if there isn't one provided in the theme.
diff --git a/packages/flutter/lib/src/material/pickers/date_range_picker_dialog.dart b/packages/flutter/lib/src/material/pickers/date_range_picker_dialog.dart
index aa8f991..5c88434d 100644
--- a/packages/flutter/lib/src/material/pickers/date_range_picker_dialog.dart
+++ b/packages/flutter/lib/src/material/pickers/date_range_picker_dialog.dart
@@ -407,9 +407,7 @@
         final DialogTheme dialogTheme = Theme.of(context).dialogTheme;
         size = orientation == Orientation.portrait ? _inputPortraitDialogSize : _inputLandscapeDialogSize;
         insetPadding = const EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0);
-        // The default dialog shape is radius 2 rounded rect, but the spec has
-        // been updated to 4, so we will use that here for the Input Date Range
-        // Picker, but only if there isn't one provided in the theme.
+        // TODO(Piinks): remove once border radius migration is complete
         shape = dialogTheme.shape ?? const RoundedRectangleBorder(
           borderRadius: BorderRadius.all(Radius.circular(4.0))
         );
diff --git a/packages/flutter/lib/src/material/time_picker.dart b/packages/flutter/lib/src/material/time_picker.dart
index 066a143..3b705c1 100644
--- a/packages/flutter/lib/src/material/time_picker.dart
+++ b/packages/flutter/lib/src/material/time_picker.dart
@@ -23,6 +23,10 @@
 import 'theme_data.dart';
 import 'time.dart';
 
+// TODO(Piinks): remove ignoring deprecated member use analysis
+//   * when Dialog.useMaterialBorderRadius parameter is removed.
+// ignore_for_file: deprecated_member_use_from_same_package
+
 // Examples can assume:
 // BuildContext context;
 
@@ -1501,12 +1505,24 @@
   const _TimePickerDialog({
     Key key,
     @required this.initialTime,
+    bool useMaterialBorderRadius,
   }) : assert(initialTime != null),
+       useMaterialBorderRadius = useMaterialBorderRadius ?? false,
        super(key: key);
 
   /// The time initially selected when the dialog is shown.
   final TimeOfDay initialTime;
 
+  /// Indicates whether the [Dialog.shape]'s default [RoundedRectangleBorder]
+  /// should have a radius of 4.0 pixels to match Material Design, or use the
+  /// prior default of 2.0 pixels.
+  @Deprecated(
+    'Set useMaterialBorderRadius to `true`. This parameter will be removed and '
+    'was introduced to migrate Dialog to the correct border radius by default. '
+    'This feature was deprecated after v1.18.0.'
+  )
+  final bool useMaterialBorderRadius;
+
   @override
   _TimePickerDialogState createState() => _TimePickerDialogState();
 }
@@ -1650,6 +1666,7 @@
     );
 
     final Dialog dialog = Dialog(
+      useMaterialBorderRadius: widget.useMaterialBorderRadius,
       child: OrientationBuilder(
         builder: (BuildContext context, Orientation orientation) {
           final Widget header = _TimePickerHeader(
@@ -1744,6 +1761,11 @@
 /// The returned Future resolves to the time selected by the user when the user
 /// closes the dialog. If the user cancels the dialog, null is returned.
 ///
+/// The [useMaterialBorderRadius] parameter specifies whether th default
+/// [Dialog.shape] of the time picker, a [RoundedRectangleBorder], should have a
+/// radius of 4.0 pixels to match Material Design, or use the prior default of
+/// 2.0 pixels.
+///
 /// {@tool snippet}
 /// Show a dialog with [initialTime] equal to the current time.
 ///
@@ -1806,13 +1828,22 @@
   TransitionBuilder builder,
   bool useRootNavigator = true,
   RouteSettings routeSettings,
+  @Deprecated(
+    'Set useMaterialBorderRadius to `true`. This parameter will be removed and '
+    'was introduced to migrate Dialog to the correct border radius by default. '
+    'This feature was deprecated after v1.18.0.'
+  )
+  bool useMaterialBorderRadius,
 }) async {
   assert(context != null);
   assert(initialTime != null);
   assert(useRootNavigator != null);
   assert(debugCheckHasMaterialLocalizations(context));
 
-  final Widget dialog = _TimePickerDialog(initialTime: initialTime);
+  final Widget dialog = _TimePickerDialog(
+    initialTime: initialTime,
+    useMaterialBorderRadius: useMaterialBorderRadius ?? false,
+  );
   return await showDialog<TimeOfDay>(
     context: context,
     useRootNavigator: useRootNavigator,
diff --git a/packages/flutter/test/material/dialog_test.dart b/packages/flutter/test/material/dialog_test.dart
index 9d579bb..19876c7 100644
--- a/packages/flutter/test/material/dialog_test.dart
+++ b/packages/flutter/test/material/dialog_test.dart
@@ -44,7 +44,7 @@
   return tester.element<StatelessElement>(find.descendant(of: find.byType(AlertDialog), matching: find.text(text))).renderObject as RenderParagraph;
 }
 
-const ShapeBorder _defaultDialogShape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.0)));
+const ShapeBorder _defaultDialogShape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0)));
 
 void main() {
   testWidgets('Dialog is scrollable', (WidgetTester tester) async {
@@ -94,6 +94,7 @@
       title: Text('Title'),
       content: Text('Y'),
       actions: <Widget>[ ],
+      useMaterialBorderRadius: true,
     );
     await tester.pumpWidget(_buildAppWithDialog(dialog, theme: ThemeData(brightness: Brightness.dark)));
 
@@ -189,6 +190,7 @@
     const AlertDialog dialog = AlertDialog(
       actions: <Widget>[ ],
       shape: null,
+      useMaterialBorderRadius: true,
     );
     await tester.pumpWidget(_buildAppWithDialog(dialog));