use ShapeBorder to draw avatar check on chip (#25984)

Adds avatarBorder property to SelectableChipAttributes and uses the outer path to draw the darkened layer.
diff --git a/packages/flutter/lib/src/material/chip.dart b/packages/flutter/lib/src/material/chip.dart
index 41a3bf1..af83b4e 100644
--- a/packages/flutter/lib/src/material/chip.dart
+++ b/packages/flutter/lib/src/material/chip.dart
@@ -304,6 +304,14 @@
   /// Tooltip string to be used for the body area (where the label and avatar
   /// are) of the chip.
   String get tooltip;
+
+  /// The shape of the translucent highlight painted over the avatar when the
+  /// [selected] property is true.
+  ///
+  /// Only the outer path of the shape is used.
+  ///
+  /// Defaults to [CircleBorder].
+  ShapeBorder get avatarBorder;
 }
 
 /// An interface for material design chips that can be enabled and disabled.
@@ -604,6 +612,7 @@
     this.backgroundColor,
     this.padding,
     this.materialTapTargetSize,
+    this.avatarBorder = const CircleBorder(),
   })  : assert(selected != null),
         assert(isEnabled != null),
         assert(label != null),
@@ -652,6 +661,8 @@
   final EdgeInsetsGeometry padding;
   @override
   final MaterialTapTargetSize materialTapTargetSize;
+  @override
+  final ShapeBorder avatarBorder;
 
   @override
   Widget build(BuildContext context) {
@@ -679,6 +690,7 @@
       padding: padding,
       materialTapTargetSize: materialTapTargetSize,
       isEnabled: isEnabled && (onSelected != null || onDeleted != null || onPressed != null),
+      avatarBorder: avatarBorder,
     );
   }
 }
@@ -762,6 +774,7 @@
     this.backgroundColor,
     this.padding,
     this.materialTapTargetSize,
+    this.avatarBorder = const CircleBorder(),
   })  : assert(selected != null),
         assert(label != null),
         assert(clipBehavior != null),
@@ -797,6 +810,8 @@
   final EdgeInsetsGeometry padding;
   @override
   final MaterialTapTargetSize materialTapTargetSize;
+  @override
+  final ShapeBorder avatarBorder;
 
   @override
   bool get isEnabled => onSelected != null;
@@ -824,6 +839,7 @@
       padding: padding,
       isEnabled: isEnabled,
       materialTapTargetSize: materialTapTargetSize,
+      avatarBorder: avatarBorder,
     );
   }
 }
@@ -939,6 +955,7 @@
     this.backgroundColor,
     this.padding,
     this.materialTapTargetSize,
+    this.avatarBorder = const CircleBorder(),
   })  : assert(selected != null),
         assert(label != null),
         assert(clipBehavior != null),
@@ -974,6 +991,8 @@
   final EdgeInsetsGeometry padding;
   @override
   final MaterialTapTargetSize materialTapTargetSize;
+  @override
+  final ShapeBorder avatarBorder;
 
   @override
   bool get isEnabled => onSelected != null;
@@ -998,6 +1017,7 @@
       padding: padding,
       isEnabled: isEnabled,
       materialTapTargetSize: materialTapTargetSize,
+      avatarBorder: avatarBorder,
     );
   }
 }
@@ -1190,6 +1210,7 @@
     this.clipBehavior = Clip.none,
     this.backgroundColor,
     this.materialTapTargetSize,
+    this.avatarBorder = const CircleBorder(),
   })  : assert(label != null),
         assert(isEnabled != null),
         assert(clipBehavior != null),
@@ -1239,6 +1260,8 @@
   final EdgeInsetsGeometry padding;
   @override
   final MaterialTapTargetSize materialTapTargetSize;
+  @override
+  final CircleBorder avatarBorder;
 
   /// Whether or not to show a check mark when [selected] is true.
   ///
@@ -1544,6 +1567,7 @@
               avatarDrawerAnimation: avatarDrawerAnimation,
               deleteDrawerAnimation: deleteDrawerAnimation,
               isEnabled: widget.isEnabled,
+              avatarBorder: widget.avatarBorder,
             ),
           ),
         ),
@@ -1624,6 +1648,7 @@
     this.avatarDrawerAnimation,
     this.deleteDrawerAnimation,
     this.enableAnimation,
+    this.avatarBorder,
   })  : assert(theme != null),
         super(key: key);
 
@@ -1634,6 +1659,7 @@
   final Animation<double> avatarDrawerAnimation;
   final Animation<double> deleteDrawerAnimation;
   final Animation<double> enableAnimation;
+  final ShapeBorder avatarBorder;
 
   @override
   _RenderChipElement createElement() => _RenderChipElement(this);
@@ -1648,7 +1674,8 @@
       ..checkmarkAnimation = checkmarkAnimation
       ..avatarDrawerAnimation = avatarDrawerAnimation
       ..deleteDrawerAnimation = deleteDrawerAnimation
-      ..enableAnimation = enableAnimation;
+      ..enableAnimation = enableAnimation
+      ..avatarBorder = avatarBorder;
   }
 
   @override
@@ -1662,6 +1689,7 @@
       avatarDrawerAnimation: avatarDrawerAnimation,
       deleteDrawerAnimation: deleteDrawerAnimation,
       enableAnimation: enableAnimation,
+      avatarBorder: avatarBorder,
     );
   }
 }
@@ -1849,6 +1877,7 @@
     this.avatarDrawerAnimation,
     this.deleteDrawerAnimation,
     this.enableAnimation,
+    this.avatarBorder,
   })  : assert(theme != null),
         assert(textDirection != null),
         _theme = theme,
@@ -1870,6 +1899,7 @@
   Animation<double> avatarDrawerAnimation;
   Animation<double> deleteDrawerAnimation;
   Animation<double> enableAnimation;
+  ShapeBorder avatarBorder;
 
   RenderBox _updateChild(RenderBox oldChild, RenderBox newChild, _ChipSlot slot) {
     if (oldChild != null) {
@@ -2357,7 +2387,8 @@
         final Paint darkenPaint = Paint()
           ..color = selectionScrimTween.evaluate(checkmarkAnimation)
           ..blendMode = BlendMode.srcATop;
-        context.canvas.drawRect(avatarRect, darkenPaint);
+        final Path path =  avatarBorder.getOuterPath(avatarRect);
+        context.canvas.drawPath(path, darkenPaint);
       }
       // Need to make the check mark be a little smaller than the avatar.
       final double checkSize = avatar.size.height * 0.75;
diff --git a/packages/flutter/test/material/chip_test.dart b/packages/flutter/test/material/chip_test.dart
index f73e2fd..6bef5b8 100644
--- a/packages/flutter/test/material/chip_test.dart
+++ b/packages/flutter/test/material/chip_test.dart
@@ -1596,4 +1596,27 @@
     await tester.pumpWidget(_wrapForChip(child: const InputChip(label: label, clipBehavior: Clip.antiAlias)));
     checkChipMaterialClipBehavior(tester, Clip.antiAlias);
   });
+
+  testWidgets('selected chip and avatar draw darkened layer within avatar circle', (WidgetTester tester) async {
+    await tester.pumpWidget(_wrapForChip(child: const FilterChip(
+      avatar: CircleAvatar(child: Text('t')),
+      label: Text('test'),
+      selected: true,
+      onSelected: null,
+    )));
+    final RenderBox rawChip = tester.firstRenderObject<RenderBox>(
+      find.descendant(
+        of: find.byType(RawChip),
+        matching: find.byWidgetPredicate((Widget widget) {
+          return widget.runtimeType.toString() == '_ChipRenderWidget';
+        })
+      )
+    );
+    const Color selectScrimColor = Color(0x60191919);
+    expect(rawChip, paints..path(color: selectScrimColor, includes: <Offset>[
+      const Offset(10, 10),
+    ], excludes: <Offset>[
+      const Offset(4, 4),
+    ]));
+  });
 }