Increase time picker clock touch targets to 48 by 48 (#19936)

diff --git a/packages/flutter/lib/src/material/time_picker.dart b/packages/flutter/lib/src/material/time_picker.dart
index 46cad86..46ddff9 100644
--- a/packages/flutter/lib/src/material/time_picker.dart
+++ b/packages/flutter/lib/src/material/time_picker.dart
@@ -327,6 +327,7 @@
       child: new Semantics(
         hint: localizations.timePickerHourModeAnnouncement,
         value: formattedHour,
+        excludeSemantics: true,
         increasedValue: formattedNextHour,
         onIncrease: () {
           fragmentContext.onTimeChange(nextHour);
@@ -335,10 +336,8 @@
         onDecrease: () {
           fragmentContext.onTimeChange(previousHour);
         },
-        child: new ExcludeSemantics(
           child: new Text(formattedHour, style: hourStyle),
         ),
-      ),
     );
   }
 }
@@ -378,12 +377,10 @@
         ? fragmentContext.activeStyle
         : fragmentContext.inactiveStyle;
     final String formattedMinute = localizations.formatMinute(fragmentContext.selectedTime);
-
     final TimeOfDay nextMinute = fragmentContext.selectedTime.replacing(
       minute: (fragmentContext.selectedTime.minute + 1) % TimeOfDay.minutesPerHour,
     );
     final String formattedNextMinute = localizations.formatMinute(nextMinute);
-
     final TimeOfDay previousMinute = fragmentContext.selectedTime.replacing(
       minute: (fragmentContext.selectedTime.minute - 1) % TimeOfDay.minutesPerHour,
     );
@@ -392,6 +389,7 @@
     return new GestureDetector(
       onTap: Feedback.wrapForTap(() => fragmentContext.onModeChange(_TimePickerMode.minute), context),
       child: new Semantics(
+        excludeSemantics: true,
         hint: localizations.timePickerMinuteModeAnnouncement,
         value: formattedMinute,
         increasedValue: formattedNextMinute,
@@ -402,10 +400,8 @@
         onDecrease: () {
           fragmentContext.onTimeChange(previousMinute);
         },
-        child: new ExcludeSemantics(
           child: new Text(formattedMinute, style: minuteStyle),
         ),
-      ),
     );
   }
 }
@@ -935,21 +931,24 @@
       if (labels == null)
         return;
       final double labelThetaIncrement = -_kTwoPi / labels.length;
+      final double ordinalOffset = ring == _DialRing.inner ? 12.0 : 0.0;
       double labelTheta = math.pi / 2.0;
 
-      for (_TappableLabel label in labels) {
+      for (int i = 0; i < labels.length; i++) {
+        final _TappableLabel label = labels[i];
         final TextPainter labelPainter = label.painter;
         final double width = labelPainter.width * _semanticNodeSizeScale;
         final double height = labelPainter.height * _semanticNodeSizeScale;
         final Offset nodeOffset = getOffsetForTheta(labelTheta, ring) + new Offset(-width / 2.0, -height / 2.0);
         final CustomPainterSemantics node = new CustomPainterSemantics(
           rect: new Rect.fromLTRB(
-            nodeOffset.dx,
-            nodeOffset.dy,
-            nodeOffset.dx + width,
-            nodeOffset.dy + height
+            nodeOffset.dx - 24.0 + width / 2,
+            nodeOffset.dy - 24.0 + height / 2,
+            nodeOffset.dx + 24.0 + width / 2,
+            nodeOffset.dy + 24.0 + height / 2,
           ),
           properties: new SemanticsProperties(
+            sortKey: new OrdinalSortKey(i.toDouble() + ordinalOffset),
             selected: label.value == selectedValue,
             value: labelPainter.text.text,
             textDirection: textDirection,
@@ -960,7 +959,6 @@
             const SemanticsTag('dial-label'),
           ]),
         );
-
         nodes.add(node);
         labelTheta += labelThetaIncrement;
       }
diff --git a/packages/flutter/lib/src/rendering/custom_paint.dart b/packages/flutter/lib/src/rendering/custom_paint.dart
index 313ed60..bf8ef59 100644
--- a/packages/flutter/lib/src/rendering/custom_paint.dart
+++ b/packages/flutter/lib/src/rendering/custom_paint.dart
@@ -809,7 +809,9 @@
 
     final SemanticsProperties properties = newSemantics.properties;
     final SemanticsConfiguration config = new SemanticsConfiguration();
-
+    if (properties.sortKey != null) {
+      config.sortKey = properties.sortKey;
+    }
     if (properties.checked != null) {
       config.isChecked = properties.checked;
     }
diff --git a/packages/flutter/test/material/time_picker_test.dart b/packages/flutter/test/material/time_picker_test.dart
index d98a32a..7b328ae 100644
--- a/packages/flutter/test/material/time_picker_test.dart
+++ b/packages/flutter/test/material/time_picker_test.dart
@@ -326,30 +326,30 @@
     final CustomPainter dialPainter = dialPaint.painter;
     final _CustomPainterSemanticsTester painterTester = new _CustomPainterSemanticsTester(tester, dialPainter, semantics);
 
-    painterTester.addLabel('00', 86.0, 12.0, 134.0, 36.0);
-    painterTester.addLabel('13', 129.0, 23.5, 177.0, 47.5);
-    painterTester.addLabel('14', 160.5, 55.0, 208.5, 79.0);
-    painterTester.addLabel('15', 172.0, 98.0, 220.0, 122.0);
-    painterTester.addLabel('16', 160.5, 141.0, 208.5, 165.0);
-    painterTester.addLabel('17', 129.0, 172.5, 177.0, 196.5);
-    painterTester.addLabel('18', 86.0, 184.0, 134.0, 208.0);
-    painterTester.addLabel('19', 43.0, 172.5, 91.0, 196.5);
-    painterTester.addLabel('20', 11.5, 141.0, 59.5, 165.0);
-    painterTester.addLabel('21', 0.0, 98.0, 48.0, 122.0);
-    painterTester.addLabel('22', 11.5, 55.0, 59.5, 79.0);
-    painterTester.addLabel('23', 43.0, 23.5, 91.0, 47.5);
-    painterTester.addLabel('12', 86.0, 48.0, 134.0, 72.0);
-    painterTester.addLabel('01', 111.0, 54.7, 159.0, 78.7);
-    painterTester.addLabel('02', 129.3, 73.0, 177.3, 97.0);
-    painterTester.addLabel('03', 136.0, 98.0, 184.0, 122.0);
-    painterTester.addLabel('04', 129.3, 123.0, 177.3, 147.0);
-    painterTester.addLabel('05', 111.0, 141.3, 159.0, 165.3);
-    painterTester.addLabel('06', 86.0, 148.0, 134.0, 172.0);
-    painterTester.addLabel('07', 61.0, 141.3, 109.0, 165.3);
-    painterTester.addLabel('08', 42.7, 123.0, 90.7, 147.0);
-    painterTester.addLabel('09', 36.0, 98.0, 84.0, 122.0);
-    painterTester.addLabel('10', 42.7, 73.0, 90.7, 97.0);
-    painterTester.addLabel('11', 61.0, 54.7, 109.0, 78.7);
+    painterTester.addLabel('00', 86.0, 0.0, 134.0, 48.0);
+    painterTester.addLabel('13', 129.0, 11.5, 177.0, 59.5);
+    painterTester.addLabel('14', 160.5, 43.0, 208.5, 91.0);
+    painterTester.addLabel('15', 172.0, 86.0, 220.0, 134.0);
+    painterTester.addLabel('16', 160.5, 129.0, 208.5, 177.0);
+    painterTester.addLabel('17', 129.0, 160.5, 177.0, 208.5);
+    painterTester.addLabel('18', 86.0, 172.0, 134.0, 220.0);
+    painterTester.addLabel('19', 43.0, 160.5, 91.0, 208.5);
+    painterTester.addLabel('20', 11.5, 129.0, 59.5, 177.0);
+    painterTester.addLabel('21', 0.0, 86.0, 48.0, 134.0);
+    painterTester.addLabel('22', 11.5, 43.0, 59.5, 91.0);
+    painterTester.addLabel('23', 43.0, 11.5, 91.0, 59.5);
+    painterTester.addLabel('12', 86.0, 36.0, 134.0, 84.0);
+    painterTester.addLabel('01', 111.0, 42.7, 159.0, 90.7);
+    painterTester.addLabel('02', 129.3, 61.0, 177.3, 109.0);
+    painterTester.addLabel('03', 136.0, 86.0, 184.0, 134.0);
+    painterTester.addLabel('04', 129.3, 111.0, 177.3, 159.0);
+    painterTester.addLabel('05', 111.0, 129.3, 159.0, 177.3);
+    painterTester.addLabel('06', 86.0, 136.0, 134.0, 184.0);
+    painterTester.addLabel('07', 61.0, 129.3, 109.0, 177.3);
+    painterTester.addLabel('08', 42.7, 111.0, 90.7, 159.0);
+    painterTester.addLabel('09', 36.0, 86.0, 84.0, 134.0);
+    painterTester.addLabel('10', 42.7, 61.0, 90.7, 109.0);
+    painterTester.addLabel('11', 61.0, 42.7, 109.0, 90.7);
 
     painterTester.assertExpectations();
     semantics.dispose();
@@ -365,18 +365,18 @@
     final CustomPainter dialPainter = dialPaint.painter;
     final _CustomPainterSemanticsTester painterTester = new _CustomPainterSemanticsTester(tester, dialPainter, semantics);
 
-    painterTester.addLabel('00', 86.0, 12.0, 134.0, 36.0);
-    painterTester.addLabel('05', 129.0, 23.5, 177.0, 47.5);
-    painterTester.addLabel('10', 160.5, 55.0, 208.5, 79.0);
-    painterTester.addLabel('15', 172.0, 98.0, 220.0, 122.0);
-    painterTester.addLabel('20', 160.5, 141.0, 208.5, 165.0);
-    painterTester.addLabel('25', 129.0, 172.5, 177.0, 196.5);
-    painterTester.addLabel('30', 86.0, 184.0, 134.0, 208.0);
-    painterTester.addLabel('35', 43.0, 172.5, 91.0, 196.5);
-    painterTester.addLabel('40', 11.5, 141.0, 59.5, 165.0);
-    painterTester.addLabel('45', 0.0, 98.0, 48.0, 122.0);
-    painterTester.addLabel('50', 11.5, 55.0, 59.5, 79.0);
-    painterTester.addLabel('55', 43.0, 23.5, 91.0, 47.5);
+    painterTester.addLabel('00', 86.0, 0.0, 134.0, 48.0);
+    painterTester.addLabel('05', 129.0, 11.5, 177.0, 59.5);
+    painterTester.addLabel('10', 160.5, 43.0, 208.5, 91.0);
+    painterTester.addLabel('15', 172.0, 86.0, 220.0, 134.0);
+    painterTester.addLabel('20', 160.5, 129.0, 208.5, 177.0);
+    painterTester.addLabel('25', 129.0, 160.5, 177.0, 208.5);
+    painterTester.addLabel('30', 86.0, 172.0, 134.0, 220.0);
+    painterTester.addLabel('35', 43.0, 160.5, 91.0, 208.5);
+    painterTester.addLabel('40', 11.5, 129.0, 59.5, 177.0);
+    painterTester.addLabel('45', 0.0, 86.0, 48.0, 134.0);
+    painterTester.addLabel('50', 11.5, 43.0, 59.5, 91.0);
+    painterTester.addLabel('55', 43.0, 11.5, 91.0, 59.5);
 
     painterTester.assertExpectations();
     semantics.dispose();