Make UserAccountsDrawerHeader accessible (#13711)

* other accounts a11y; show accounts button a11y

* layout with bigger tap areas; all semantics

* internationalize UserAccountsDrawerHeader a11y labels

* better Russian translation

* break import cycle

* address comments
diff --git a/packages/flutter/lib/src/material/material_localizations.dart b/packages/flutter/lib/src/material/material_localizations.dart
index 481fae8..3053cea 100644
--- a/packages/flutter/lib/src/material/material_localizations.dart
+++ b/packages/flutter/lib/src/material/material_localizations.dart
@@ -239,6 +239,18 @@
   /// ```
   int get firstDayOfWeekIndex;
 
+  /// The semantics label used to indicate which account is signed in in the
+  /// [UserAccountsDrawerHeader] widget.
+  String get signedInLabel;
+
+  /// The semantics label used for the button on [UserAccountsDrawerHeader] that
+  /// hides the list of accounts.
+  String get hideAccountsLabel;
+
+  /// The semantics label used for the button on [UserAccountsDrawerHeader] that
+  /// shows the list of accounts.
+  String get showAccountsLabel;
+
   /// The `MaterialLocalizations` from the closest [Localizations] instance
   /// that encloses the given context.
   ///
@@ -570,6 +582,15 @@
   @override
   TextTheme get localTextGeometry => MaterialTextGeometry.englishLike;
 
+  @override
+  String get signedInLabel => 'Signed in';
+
+  @override
+  String get hideAccountsLabel => 'Hide accounts';
+
+  @override
+  String get showAccountsLabel => 'Show accounts';
+
   /// Creates an object that provides US English resource values for the material
   /// library widgets.
   ///
diff --git a/packages/flutter/lib/src/material/user_accounts_drawer_header.dart b/packages/flutter/lib/src/material/user_accounts_drawer_header.dart
index d793a85..1558929 100644
--- a/packages/flutter/lib/src/material/user_accounts_drawer_header.dart
+++ b/packages/flutter/lib/src/material/user_accounts_drawer_header.dart
@@ -10,6 +10,7 @@
 import 'drawer_header.dart';
 import 'icons.dart';
 import 'ink_well.dart';
+import 'material_localizations.dart';
 import 'theme.dart';
 
 class _AccountPictures extends StatelessWidget {
@@ -35,7 +36,10 @@
                 margin: const EdgeInsetsDirectional.only(start: 16.0),
                 width: 40.0,
                 height: 40.0,
-                child: picture
+                child: new Semantics(
+                  container: true,
+                  child: picture,
+                ),
               );
             }).toList(),
           ),
@@ -45,7 +49,7 @@
           child: new SizedBox(
             width: 72.0,
             height: 72.0,
-            child: currentAccountPicture
+            child: currentAccountPicture,
           ),
         ),
       ],
@@ -67,62 +71,72 @@
   final VoidCallback onTap;
   final bool isOpen;
 
-  Widget addDropdownIcon(Widget line) {
-    final Widget icon = new Icon(
-      isOpen ? Icons.arrow_drop_up : Icons.arrow_drop_down,
-      color: Colors.white
-    );
-    return new Expanded(
-      child: new Row(
-        crossAxisAlignment: CrossAxisAlignment.center,
-        children: line == null ? <Widget>[icon] : <Widget>[
-          new Expanded(child: line),
-          icon,
-        ],
-      ),
-    );
-  }
-
   @override
   Widget build(BuildContext context) {
     final ThemeData theme = Theme.of(context);
-    Widget accountNameLine = accountName == null ? null : new DefaultTextStyle(
+    final MaterialLocalizations localizations = MaterialLocalizations.of(context);
+    final Widget accountNameLine = accountName == null ? null : new DefaultTextStyle(
       style: theme.primaryTextTheme.body2,
       overflow: TextOverflow.ellipsis,
       child: accountName,
     );
-    Widget accountEmailLine = accountEmail == null ? null : new DefaultTextStyle(
+    final Widget accountEmailLine = accountEmail == null ? null : new DefaultTextStyle(
       style: theme.primaryTextTheme.body1,
       overflow: TextOverflow.ellipsis,
       child: accountEmail,
     );
-    if (onTap != null) {
-      if (accountEmailLine != null)
-        accountEmailLine = addDropdownIcon(accountEmailLine);
-      else
-        accountNameLine = addDropdownIcon(accountNameLine);
-    }
 
-    Widget accountDetails;
+    final List<Widget> rowChildren = <Widget>[];
+
     if (accountEmailLine != null || accountNameLine != null) {
-      accountDetails = new Padding(
-        padding: const EdgeInsets.symmetric(vertical: 8.0),
-        child: new Column(
-          crossAxisAlignment: CrossAxisAlignment.start,
-          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
-          children: (accountEmailLine != null && accountNameLine != null)
-            ? <Widget>[accountNameLine, accountEmailLine]
-            : <Widget>[accountNameLine ?? accountEmailLine]
+      rowChildren.add(
+        new Expanded(
+          flex: 1,
+          child: new Padding(
+            padding: const EdgeInsets.fromLTRB(16.0, 8.0, 0.0, 8.0),
+            child: new Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+              children: (accountEmailLine != null && accountNameLine != null)
+                  ? <Widget>[accountNameLine, accountEmailLine]
+                  : <Widget>[accountNameLine ?? accountEmailLine],
+            ),
+          ),
         ),
       );
     }
 
-    if (onTap != null)
-      accountDetails = new InkWell(onTap: onTap, child: accountDetails);
+    const double kAccountDetailsHeight = 56.0;
+
+    if (onTap != null) {
+      rowChildren.add(
+        new InkWell(
+          onTap: onTap,
+          child: new Semantics(
+            button: true,
+            child: new SizedBox(
+              height: kAccountDetailsHeight,
+              width: kAccountDetailsHeight,  // make it a square
+              child: new Center(
+                child: new Icon(
+                  isOpen ? Icons.arrow_drop_up : Icons.arrow_drop_down,
+                  color: Colors.white,
+                  semanticLabel: isOpen
+                    ? localizations.hideAccountsLabel
+                    : localizations.showAccountsLabel,
+                ),
+              ),
+            ),
+          ),
+        ),
+      );
+    }
 
     return new SizedBox(
-      height: 56.0,
-      child: accountDetails,
+      height: kAccountDetailsHeight,
+      child: new Row(
+        children: rowChildren,
+      ),
     );
   }
 }
@@ -147,7 +161,7 @@
     this.otherAccountsPictures,
     @required this.accountName,
     @required this.accountEmail,
-    this.onDetailsPressed
+    this.onDetailsPressed,
   }) : super(key: key);
 
   /// The header's background. If decoration is null then a [BoxDecoration]
@@ -200,24 +214,32 @@
         color: Theme.of(context).primaryColor,
       ),
       margin: widget.margin,
+      padding: EdgeInsets.zero,
       child: new SafeArea(
         bottom: false,
-        child: new Column(
-          crossAxisAlignment: CrossAxisAlignment.stretch,
-          children: <Widget>[
-            new Expanded(
-              child: new _AccountPictures(
-                currentAccountPicture: widget.currentAccountPicture,
-                otherAccountsPictures: widget.otherAccountsPictures,
-              )
-            ),
-            new _AccountDetails(
-              accountName: widget.accountName,
-              accountEmail: widget.accountEmail,
-              isOpen: _isOpen,
-              onTap: widget.onDetailsPressed == null ? null : _handleDetailsPressed,
-            ),
-          ],
+        child: new Semantics(
+          container: true,
+          label: 'Signed in',
+          child: new Column(
+            crossAxisAlignment: CrossAxisAlignment.stretch,
+            children: <Widget>[
+              new Expanded(
+                child: new Padding(
+                  padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 0.0),
+                  child: new _AccountPictures(
+                    currentAccountPicture: widget.currentAccountPicture,
+                    otherAccountsPictures: widget.otherAccountsPictures,
+                  ),
+                ),
+              ),
+              new _AccountDetails(
+                accountName: widget.accountName,
+                accountEmail: widget.accountEmail,
+                isOpen: _isOpen,
+                onTap: widget.onDetailsPressed == null ? null : _handleDetailsPressed,
+              ),
+            ],
+          ),
         ),
       ),
     );
diff --git a/packages/flutter/lib/src/widgets/basic.dart b/packages/flutter/lib/src/widgets/basic.dart
index 511e2bb..0ce80b6 100644
--- a/packages/flutter/lib/src/widgets/basic.dart
+++ b/packages/flutter/lib/src/widgets/basic.dart
@@ -4826,7 +4826,7 @@
   /// more accessible.
   final SemanticsProperties properties;
 
-  /// If 'container' is true, this widget will introduce a new
+  /// If [container] is true, this widget will introduce a new
   /// node in the semantics tree. Otherwise, the semantics will be
   /// merged with the semantics of any ancestors (if the ancestor allows that).
   ///
diff --git a/packages/flutter/test/material/user_accounts_drawer_header_test.dart b/packages/flutter/test/material/user_accounts_drawer_header_test.dart
index f18956e..a68288a 100644
--- a/packages/flutter/test/material/user_accounts_drawer_header_test.dart
+++ b/packages/flutter/test/material/user_accounts_drawer_header_test.dart
@@ -2,58 +2,71 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'dart:ui';
+
 import 'package:flutter/material.dart';
 import 'package:flutter/rendering.dart';
-import 'package:flutter_test/flutter_test.dart';
+import 'package:flutter_test/flutter_test.dart' hide TypeMatcher;
 
-void main() {
-  testWidgets('UserAccountsDrawerHeader test', (WidgetTester tester) async {
-    final Key avatarA = const Key('A');
-    final Key avatarC = const Key('C');
-    final Key avatarD = const Key('D');
+import '../widgets/semantics_tester.dart';
 
-    await tester.pumpWidget(
-      new MaterialApp(
-        home: new MediaQuery(
-          data: const MediaQueryData(
-            padding: const EdgeInsets.only(
-              left: 10.0,
-              top: 20.0,
-              right: 30.0,
-              bottom: 40.0,
-            ),
+const Key avatarA = const Key('A');
+const Key avatarC = const Key('C');
+const Key avatarD = const Key('D');
+
+Future<Null> pumpTestWidget(WidgetTester tester, {
+  bool withName: true,
+  bool withEmail: true,
+  bool withOnDetailsPressedHandler: true,
+}) async {
+  await tester.pumpWidget(
+    new MaterialApp(
+      home: new MediaQuery(
+        data: const MediaQueryData(
+          padding: const EdgeInsets.only(
+            left: 10.0,
+            top: 20.0,
+            right: 30.0,
+            bottom: 40.0,
           ),
-          child: new Material(
-            child: new Center(
-              child: new UserAccountsDrawerHeader(
-                currentAccountPicture: new CircleAvatar(
-                  key: avatarA,
-                  child: const Text('A'),
-                ),
-                otherAccountsPictures: <Widget>[
-                  const CircleAvatar(
-                    child: const Text('B'),
-                  ),
-                  new CircleAvatar(
-                    key: avatarC,
-                    child: const Text('C'),
-                  ),
-                  new CircleAvatar(
-                    key: avatarD,
-                    child: const Text('D'),
-                  ),
-                  const CircleAvatar(
-                    child: const Text('E'),
-                  )
-                ],
-                accountName: const Text('name'),
-                accountEmail: const Text('email'),
+        ),
+        child: new Material(
+          child: new Center(
+            child: new UserAccountsDrawerHeader(
+              onDetailsPressed: withOnDetailsPressedHandler ? () {} : null,
+              currentAccountPicture: const CircleAvatar(
+                key: avatarA,
+                child: const Text('A'),
               ),
+              otherAccountsPictures: <Widget>[
+                const CircleAvatar(
+                  child: const Text('B'),
+                ),
+                const CircleAvatar(
+                  key: avatarC,
+                  child: const Text('C'),
+                ),
+                const CircleAvatar(
+                  key: avatarD,
+                  child: const Text('D'),
+                ),
+                const CircleAvatar(
+                  child: const Text('E'),
+                )
+              ],
+              accountName: withName ? const Text('name') : null,
+              accountEmail: withEmail ? const Text('email') : null,
             ),
           ),
         ),
       ),
-    );
+    ),
+  );
+}
+
+void main() {
+  testWidgets('UserAccountsDrawerHeader layout', (WidgetTester tester) async {
+    await pumpTestWidget(tester);
 
     expect(find.text('A'), findsOneWidget);
     expect(find.text('B'), findsOneWidget);
@@ -126,6 +139,8 @@
     ));
     expect(find.byType(Icon), findsOneWidget);
 
+    // When either email or account name (but not both!) are present, the icon
+    // is center aligned with the text displaying the email/name.
     await tester.pumpWidget(buildFrame(
       accountName: const Text('accountName'),
       onDetailsPressed: () { },
@@ -144,13 +159,16 @@
       tester.getCenter(find.byType(Icon)).dy
     );
 
+    // When _both_ email and account name are present, the icon is placed in the
+    // center of the entire row. It's not aligned with text any more.
     await tester.pumpWidget(buildFrame(
       accountName: const Text('accountName'),
       accountEmail: const Text('accountEmail'),
       onDetailsPressed: () { },
     ));
+    final RenderFlex row = tester.element(find.text('accountEmail')).ancestorRenderObjectOfType(const TypeMatcher<RenderFlex>());
     expect(
-      tester.getCenter(find.text('accountEmail')).dy,
+      row.localToGlobal(row.size.center(Offset.zero)).dy,
       tester.getCenter(find.byType(Icon)).dy
     );
     expect(
@@ -186,4 +204,83 @@
       greaterThan(tester.getBottomLeft(find.byKey(avatarA)).dy)
     );
   });
+
+  testWidgets('UserAccountsDrawerHeader provides semantics', (WidgetTester tester) async {
+    final SemanticsTester semantics = new SemanticsTester(tester);
+    await pumpTestWidget(tester);
+    expect(
+      semantics,
+      hasSemantics(
+        new TestSemantics(
+          children: <TestSemantics>[
+            new TestSemantics(
+              label: 'Signed in\nA\nname\nemail',
+              textDirection: TextDirection.ltr,
+              children: <TestSemantics>[
+                new TestSemantics(
+                  label: r'B',
+                  textDirection: TextDirection.ltr,
+                ),
+                new TestSemantics(
+                  label: r'C',
+                  textDirection: TextDirection.ltr,
+                ),
+                new TestSemantics(
+                  label: r'D',
+                  textDirection: TextDirection.ltr,
+                ),
+                new TestSemantics(
+                  flags: <SemanticsFlags>[SemanticsFlags.isButton],
+                  actions: <SemanticsAction>[SemanticsAction.tap],
+                  label: r'Show accounts',
+                  textDirection: TextDirection.ltr,
+                ),
+              ],
+            ),
+          ],
+        ),
+        ignoreId: true, ignoreTransform: true, ignoreRect: true,
+      ),
+    );
+    semantics.dispose();
+  });
+
+  testWidgets('UserAccountsDrawerHeader provides semantics with missing properties', (WidgetTester tester) async {
+    final SemanticsTester semantics = new SemanticsTester(tester);
+    await pumpTestWidget(
+      tester,
+      withEmail: false,
+      withName: false,
+      withOnDetailsPressedHandler: false,
+    );
+    expect(
+      semantics,
+      hasSemantics(
+        new TestSemantics(
+          children: <TestSemantics>[
+            new TestSemantics(
+              label: 'Signed in\nA',
+              textDirection: TextDirection.ltr,
+              children: <TestSemantics>[
+                new TestSemantics(
+                  label: r'B',
+                  textDirection: TextDirection.ltr,
+                ),
+                new TestSemantics(
+                  label: r'C',
+                  textDirection: TextDirection.ltr,
+                ),
+                new TestSemantics(
+                  label: r'D',
+                  textDirection: TextDirection.ltr,
+                ),
+              ],
+            ),
+          ],
+        ),
+        ignoreId: true, ignoreTransform: true, ignoreRect: true,
+      ),
+    );
+    semantics.dispose();
+  });
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/localizations.dart b/packages/flutter_localizations/lib/src/l10n/localizations.dart
index eaf1365..e720c6d 100644
--- a/packages/flutter_localizations/lib/src/l10n/localizations.dart
+++ b/packages/flutter_localizations/lib/src/l10n/localizations.dart
@@ -53,6 +53,9 @@
   String get postMeridiemAbbreviation => parent?.postMeridiemAbbreviation;
   String get timePickerHourModeAnnouncement => parent?.timePickerHourModeAnnouncement;
   String get timePickerMinuteModeAnnouncement => parent?.timePickerMinuteModeAnnouncement;
+  String get signedInLabel => parent?.signedInLabel;
+  String get hideAccountsLabel => parent?.hideAccountsLabel;
+  String get showAccountsLabel => parent?.showAccountsLabel;
   String get modalBarrierDismissLabel => parent?.modalBarrierDismissLabel;
 }
 
@@ -94,6 +97,9 @@
   @override String get postMeridiemAbbreviation => r'م';
   @override String get timePickerHourModeAnnouncement => r'اختيار الساعات';
   @override String get timePickerMinuteModeAnnouncement => r'اختيار الدقائق';
+  @override String get signedInLabel => r'تم تسجيل الدخول';
+  @override String get hideAccountsLabel => r'إخفاء الحسابات';
+  @override String get showAccountsLabel => r'عرض الحسابات';
   @override String get modalBarrierDismissLabel => r'تجاهل';
 }
 
@@ -132,6 +138,9 @@
   @override String get postMeridiemAbbreviation => r'NACHM.';
   @override String get timePickerHourModeAnnouncement => r'Stunden auswählen';
   @override String get timePickerMinuteModeAnnouncement => r'Minuten auswählen';
+  @override String get signedInLabel => r'Angemeldet';
+  @override String get hideAccountsLabel => r'Konten ausblenden';
+  @override String get showAccountsLabel => r'Konten anzeigen';
   @override String get modalBarrierDismissLabel => r'Schließen';
 }
 
@@ -171,6 +180,9 @@
   @override String get timePickerHourModeAnnouncement => r'Select hours';
   @override String get timePickerMinuteModeAnnouncement => r'Select minutes';
   @override String get modalBarrierDismissLabel => r'Dismiss';
+  @override String get signedInLabel => r'Signed in';
+  @override String get hideAccountsLabel => r'Hide accounts';
+  @override String get showAccountsLabel => r'Show accounts';
 }
 
 // ignore: camel_case_types
@@ -208,6 +220,9 @@
   @override String get postMeridiemAbbreviation => r'P.M.';
   @override String get timePickerHourModeAnnouncement => r'Seleccionar horas';
   @override String get timePickerMinuteModeAnnouncement => r'Seleccionar minutos';
+  @override String get signedInLabel => r'Registrado';
+  @override String get hideAccountsLabel => r'Ocultar cuentas';
+  @override String get showAccountsLabel => r'Mostrar cuentas';
   @override String get modalBarrierDismissLabel => r'Ignorar';
 }
 
@@ -245,6 +260,9 @@
   @override String get postMeridiemAbbreviation => r'ب.ظ.';
   @override String get timePickerHourModeAnnouncement => r'انتخاب ساعت';
   @override String get timePickerMinuteModeAnnouncement => r'انتخاب دقیقه';
+  @override String get signedInLabel => r'وارد شدن';
+  @override String get hideAccountsLabel => r'پنهان کردن حساب ها';
+  @override String get showAccountsLabel => r'نمایش حساب ها';
   @override String get modalBarrierDismissLabel => r'رد کردن';
 }
 
@@ -283,6 +301,9 @@
   @override String get postMeridiemAbbreviation => r'PM';
   @override String get timePickerHourModeAnnouncement => r'Sélectionner une heure';
   @override String get timePickerMinuteModeAnnouncement => r'Sélectionner des minutes';
+  @override String get signedInLabel => r'Connecté';
+  @override String get hideAccountsLabel => r'Masquer les comptes';
+  @override String get showAccountsLabel => r'Afficher les comptes';
   @override String get modalBarrierDismissLabel => r'Ignorer';
 }
 
@@ -359,6 +380,9 @@
   @override String get postMeridiemAbbreviation => r'PM';
   @override String get timePickerHourModeAnnouncement => r'בחירת שעות';
   @override String get timePickerMinuteModeAnnouncement => r'בחירת דקות';
+  @override String get signedInLabel => r'מחובר';
+  @override String get hideAccountsLabel => r'הסתר חשבונות';
+  @override String get showAccountsLabel => r'הצג חשבונות';
   @override String get modalBarrierDismissLabel => r'סגירה';
 }
 
@@ -396,6 +420,9 @@
   @override String get postMeridiemAbbreviation => r'PM';
   @override String get timePickerHourModeAnnouncement => r'Seleziona le ore';
   @override String get timePickerMinuteModeAnnouncement => r'Seleziona i minuti';
+  @override String get signedInLabel => r'Registrato';
+  @override String get hideAccountsLabel => r'Nascondi account';
+  @override String get showAccountsLabel => r'Mostra account';
   @override String get modalBarrierDismissLabel => r'Ignora';
 }
 
@@ -433,6 +460,9 @@
   @override String get postMeridiemAbbreviation => r'PM';
   @override String get timePickerHourModeAnnouncement => r'時間を選択';
   @override String get timePickerMinuteModeAnnouncement => r'分を選択';
+  @override String get signedInLabel => r'ログイン中';
+  @override String get hideAccountsLabel => r'アカウントを隠す';
+  @override String get showAccountsLabel => r'アカウントを表示する';
   @override String get modalBarrierDismissLabel => r'閉じる';
 }
 
@@ -470,6 +500,9 @@
   @override String get postMeridiemAbbreviation => r'오후';
   @override String get timePickerHourModeAnnouncement => r'시간 선택';
   @override String get timePickerMinuteModeAnnouncement => r'분 선택';
+  @override String get signedInLabel => r'로그인 함';
+  @override String get hideAccountsLabel => r'계정 숨기기';
+  @override String get showAccountsLabel => r'계정 표시';
   @override String get modalBarrierDismissLabel => r'버리다';
 }
 
@@ -507,6 +540,9 @@
   @override String get postMeridiemAbbreviation => r'pm';
   @override String get timePickerHourModeAnnouncement => r'Uren selecteren';
   @override String get timePickerMinuteModeAnnouncement => r'Minuten selecteren';
+  @override String get signedInLabel => r'Ingelogd';
+  @override String get hideAccountsLabel => r'Verberg accounts';
+  @override String get showAccountsLabel => r'Toon accounts';
   @override String get modalBarrierDismissLabel => r'ontslaan';
 }
 
@@ -546,6 +582,9 @@
   @override String get postMeridiemAbbreviation => r'PM';
   @override String get timePickerHourModeAnnouncement => r'Wybierz godziny';
   @override String get timePickerMinuteModeAnnouncement => r'Wybierz minuty';
+  @override String get signedInLabel => r'Zapisany';
+  @override String get hideAccountsLabel => r'Ukryj konta';
+  @override String get showAccountsLabel => r'Pokaż konta';
   @override String get modalBarrierDismissLabel => r'oddalić';
 }
 
@@ -580,6 +619,9 @@
   @override String get viewLicensesButtonLabel => r'لیدلس وګورئ';
   @override String get timePickerHourModeAnnouncement => r'وختونه وټاکئ';
   @override String get timePickerMinuteModeAnnouncement => r'منې غوره کړئ';
+  @override String get signedInLabel => r'ننوتل';
+  @override String get hideAccountsLabel => r'حسابونه پټ کړئ';
+  @override String get showAccountsLabel => r'حسابونه ښکاره کړئ';
   @override String get modalBarrierDismissLabel => r'رد کړه';
 }
 
@@ -617,6 +659,9 @@
   @override String get viewLicensesButtonLabel => r'VER LICENÇAS';
   @override String get timePickerHourModeAnnouncement => r'Selecione as horas';
   @override String get timePickerMinuteModeAnnouncement => r'Selecione os minutos';
+  @override String get signedInLabel => r'Assinado';
+  @override String get hideAccountsLabel => r'Ocultar contas';
+  @override String get showAccountsLabel => r'Mostrar contas';
   @override String get modalBarrierDismissLabel => r'Dispensar';
 }
 
@@ -657,6 +702,9 @@
   @override String get postMeridiemAbbreviation => r'PM';
   @override String get timePickerHourModeAnnouncement => r'Выберите часы';
   @override String get timePickerMinuteModeAnnouncement => r'Выберите минуты';
+  @override String get signedInLabel => r'Залогинен';
+  @override String get hideAccountsLabel => r'Спрятать аккаунты';
+  @override String get showAccountsLabel => r'Показать аккаунты';
   @override String get modalBarrierDismissLabel => r'Закрыть';
 }
 
@@ -694,6 +742,9 @@
   @override String get postMeridiemAbbreviation => r'PM';
   @override String get timePickerHourModeAnnouncement => r'เลือกชั่วโมง';
   @override String get timePickerMinuteModeAnnouncement => r'เลือกนาที';
+  @override String get signedInLabel => r'ลงทะเบียนเข้า';
+  @override String get hideAccountsLabel => r'ซ่อนบัญชี';
+  @override String get showAccountsLabel => r'แสดงบัญชี';
   @override String get modalBarrierDismissLabel => r'ยกเลิก';
 }
 
@@ -731,6 +782,9 @@
   @override String get postMeridiemAbbreviation => r'ÖS';
   @override String get timePickerHourModeAnnouncement => r'Saati seçin';
   @override String get timePickerMinuteModeAnnouncement => r'Dakikayı seçin';
+  @override String get signedInLabel => r'Yetkili';
+  @override String get hideAccountsLabel => r'Hesapları gizle';
+  @override String get showAccountsLabel => r'Hesapları göster';
   @override String get modalBarrierDismissLabel => r'Reddet';
 }
 
@@ -768,6 +822,9 @@
   @override String get postMeridiemAbbreviation => r'PM';
   @override String get timePickerHourModeAnnouncement => r'گھنٹے منتخب کریں';
   @override String get timePickerMinuteModeAnnouncement => r'منٹ منتخب کریں';
+  @override String get signedInLabel => r'سائن ان';
+  @override String get hideAccountsLabel => r'اکاؤنٹس چھپائیں';
+  @override String get showAccountsLabel => r'اکاؤنٹس دکھائیں';
   @override String get modalBarrierDismissLabel => r'برطرف';
 }
 
@@ -805,6 +862,9 @@
   @override String get postMeridiemAbbreviation => r'下午';
   @override String get timePickerHourModeAnnouncement => r'选择小时';
   @override String get timePickerMinuteModeAnnouncement => r'选择分钟';
+  @override String get signedInLabel => r'登录';
+  @override String get hideAccountsLabel => r'隐藏帐户';
+  @override String get showAccountsLabel => r'显示帐户';
   @override String get modalBarrierDismissLabel => r'关闭';
 }
 
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ar.arb b/packages/flutter_localizations/lib/src/l10n/material_ar.arb
index 93be87a..c86ee7f 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ar.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ar.arb
@@ -34,5 +34,8 @@
   "postMeridiemAbbreviation": "م",
   "timePickerHourModeAnnouncement": "اختيار الساعات",
   "timePickerMinuteModeAnnouncement": "اختيار الدقائق",
+  "signedInLabel": "تم تسجيل الدخول",
+  "hideAccountsLabel": "إخفاء الحسابات",
+  "showAccountsLabel": "عرض الحسابات",
   "modalBarrierDismissLabel": "تجاهل"
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_de.arb b/packages/flutter_localizations/lib/src/l10n/material_de.arb
index e98e311..cc0916c 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_de.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_de.arb
@@ -31,5 +31,8 @@
   "postMeridiemAbbreviation": "NACHM.",
   "timePickerHourModeAnnouncement": "Stunden auswählen",
   "timePickerMinuteModeAnnouncement": "Minuten auswählen",
+  "signedInLabel": "Angemeldet",
+  "hideAccountsLabel": "Konten ausblenden",
+  "showAccountsLabel": "Konten anzeigen",
   "modalBarrierDismissLabel": "Schließen"
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_en.arb b/packages/flutter_localizations/lib/src/l10n/material_en.arb
index 3c958cc..41e3e43 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_en.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_en.arb
@@ -158,5 +158,20 @@
   "modalBarrierDismissLabel": "Dismiss",
   "@modalBarrierDismissLabel": {
     "description": "Label read out by accessibility tools (TalkBack or VocieOver) for a modal barrier to indicate that a tap dismisses the barrier. A modal barrier can for example be found behind a alert or popup to block user interaction with elements behind it."
+  },
+
+  "signedInLabel": "Signed in",
+  "@signedInLabel": {
+    "description": "The semantics label used to indicate which account is signed in in UserAccountsDrawerHeader when an accessibility user navigates the UI."
+  },
+
+  "hideAccountsLabel": "Hide accounts",
+  "@hideAccountsLabel": {
+    "description": "The semantics label used for the button on UserAccountsDrawerHeader that hides the list of accounts."
+  },
+
+  "showAccountsLabel": "Show accounts",
+  "@showAccountsLabel": {
+    "description": "The semantics label used for the button on UserAccountsDrawerHeader that shows the list of accounts."
   }
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_es.arb b/packages/flutter_localizations/lib/src/l10n/material_es.arb
index 79cc812..2b9c8ab 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_es.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_es.arb
@@ -31,5 +31,8 @@
   "postMeridiemAbbreviation": "P.M.",
   "timePickerHourModeAnnouncement": "Seleccionar horas",
   "timePickerMinuteModeAnnouncement": "Seleccionar minutos",
+  "signedInLabel": "Registrado",
+  "hideAccountsLabel": "Ocultar cuentas",
+  "showAccountsLabel": "Mostrar cuentas",
   "modalBarrierDismissLabel": "Ignorar"
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_fa.arb b/packages/flutter_localizations/lib/src/l10n/material_fa.arb
index 2135857..84db5e5 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_fa.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_fa.arb
@@ -30,5 +30,8 @@
   "postMeridiemAbbreviation": "ب.ظ.",
   "timePickerHourModeAnnouncement": "انتخاب ساعت",
   "timePickerMinuteModeAnnouncement": "انتخاب دقیقه",
+  "signedInLabel": "وارد شدن",
+  "hideAccountsLabel": "پنهان کردن حساب ها",
+  "showAccountsLabel": "نمایش حساب ها",
   "modalBarrierDismissLabel": "رد کردن"
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_fr.arb b/packages/flutter_localizations/lib/src/l10n/material_fr.arb
index 6c834b9..62203cb 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_fr.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_fr.arb
@@ -31,5 +31,8 @@
   "postMeridiemAbbreviation": "PM",
   "timePickerHourModeAnnouncement": "Sélectionner une heure",
   "timePickerMinuteModeAnnouncement": "Sélectionner des minutes",
+  "signedInLabel": "Connecté",
+  "hideAccountsLabel": "Masquer les comptes",
+  "showAccountsLabel": "Afficher les comptes",
   "modalBarrierDismissLabel": "Ignorer"
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_he.arb b/packages/flutter_localizations/lib/src/l10n/material_he.arb
index d92dd2f..014e0f5 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_he.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_he.arb
@@ -32,5 +32,8 @@
   "postMeridiemAbbreviation": "PM",
   "timePickerHourModeAnnouncement": "בחירת שעות",
   "timePickerMinuteModeAnnouncement": "בחירת דקות",
+  "signedInLabel": "מחובר",
+  "hideAccountsLabel": "הסתר חשבונות",
+  "showAccountsLabel": "הצג חשבונות",
   "modalBarrierDismissLabel": "סגירה"
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_it.arb b/packages/flutter_localizations/lib/src/l10n/material_it.arb
index a215a74..7792e95 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_it.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_it.arb
@@ -30,5 +30,8 @@
   "postMeridiemAbbreviation": "PM",
   "timePickerHourModeAnnouncement": "Seleziona le ore",
   "timePickerMinuteModeAnnouncement": "Seleziona i minuti",
+  "signedInLabel": "Registrato",
+  "hideAccountsLabel": "Nascondi account",
+  "showAccountsLabel": "Mostra account",
   "modalBarrierDismissLabel": "Ignora"
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ja.arb b/packages/flutter_localizations/lib/src/l10n/material_ja.arb
index 1fa29a8..3af4024 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ja.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ja.arb
@@ -30,5 +30,8 @@
   "postMeridiemAbbreviation": "PM",
   "timePickerHourModeAnnouncement": "時間を選択",
   "timePickerMinuteModeAnnouncement": "分を選択",
+  "signedInLabel": "ログイン中",
+  "hideAccountsLabel": "アカウントを隠す",
+  "showAccountsLabel": "アカウントを表示する",
   "modalBarrierDismissLabel": "閉じる"
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ko.arb b/packages/flutter_localizations/lib/src/l10n/material_ko.arb
index 34f4bb6..3671acc 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ko.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ko.arb
@@ -30,5 +30,8 @@
   "postMeridiemAbbreviation": "오후",
   "timePickerHourModeAnnouncement": "시간 선택",
   "timePickerMinuteModeAnnouncement": "분 선택",
+  "signedInLabel": "로그인 함",
+  "hideAccountsLabel": "계정 숨기기",
+  "showAccountsLabel": "계정 표시",
   "modalBarrierDismissLabel": "버리다"
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_nl.arb b/packages/flutter_localizations/lib/src/l10n/material_nl.arb
index fafb427..5622fec 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_nl.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_nl.arb
@@ -30,5 +30,8 @@
   "postMeridiemAbbreviation": "pm",
   "timePickerHourModeAnnouncement": "Uren selecteren",
   "timePickerMinuteModeAnnouncement": "Minuten selecteren",
+  "signedInLabel": "Ingelogd",
+  "hideAccountsLabel": "Verberg accounts",
+  "showAccountsLabel": "Toon accounts",
   "modalBarrierDismissLabel": "ontslaan"
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_pl.arb b/packages/flutter_localizations/lib/src/l10n/material_pl.arb
index 0085d0a..c4dd4b6 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_pl.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_pl.arb
@@ -32,5 +32,8 @@
   "postMeridiemAbbreviation": "PM",
   "timePickerHourModeAnnouncement": "Wybierz godziny",
   "timePickerMinuteModeAnnouncement": "Wybierz minuty",
+  "signedInLabel": "Zapisany",
+  "hideAccountsLabel": "Ukryj konta",
+  "showAccountsLabel": "Pokaż konta",
   "modalBarrierDismissLabel": "oddalić"
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ps.arb b/packages/flutter_localizations/lib/src/l10n/material_ps.arb
index 357fb95..9677310 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ps.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ps.arb
@@ -29,5 +29,8 @@
   "viewLicensesButtonLabel": "لیدلس وګورئ",
   "timePickerHourModeAnnouncement": "وختونه وټاکئ",
   "timePickerMinuteModeAnnouncement": "منې غوره کړئ",
+  "signedInLabel": "ننوتل",
+  "hideAccountsLabel": "حسابونه پټ کړئ",
+  "showAccountsLabel": "حسابونه ښکاره کړئ",
   "modalBarrierDismissLabel": "رد کړه"
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_pt.arb b/packages/flutter_localizations/lib/src/l10n/material_pt.arb
index 72c5d25..0d1ce12 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_pt.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_pt.arb
@@ -32,5 +32,8 @@
   "viewLicensesButtonLabel": "VER LICENÇAS",
   "timePickerHourModeAnnouncement": "Selecione as horas",
   "timePickerMinuteModeAnnouncement": "Selecione os minutos",
+  "signedInLabel": "Assinado",
+  "hideAccountsLabel": "Ocultar contas",
+  "showAccountsLabel": "Mostrar contas",
   "modalBarrierDismissLabel": "Dispensar"
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ru.arb b/packages/flutter_localizations/lib/src/l10n/material_ru.arb
index 82f2f06..d91cc4a 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ru.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ru.arb
@@ -33,5 +33,8 @@
   "postMeridiemAbbreviation": "PM",
   "timePickerHourModeAnnouncement": "Выберите часы",
   "timePickerMinuteModeAnnouncement": "Выберите минуты",
+  "signedInLabel": "Залогинен",
+  "hideAccountsLabel": "Спрятать аккаунты",
+  "showAccountsLabel": "Показать аккаунты",
   "modalBarrierDismissLabel": "Закрыть"
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_th.arb b/packages/flutter_localizations/lib/src/l10n/material_th.arb
index 901aecb..3711759 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_th.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_th.arb
@@ -30,5 +30,8 @@
   "postMeridiemAbbreviation": "PM",
   "timePickerHourModeAnnouncement": "เลือกชั่วโมง",
   "timePickerMinuteModeAnnouncement": "เลือกนาที",
+  "signedInLabel": "ลงทะเบียนเข้า",
+  "hideAccountsLabel": "ซ่อนบัญชี",
+  "showAccountsLabel": "แสดงบัญชี",
   "modalBarrierDismissLabel": "ยกเลิก"
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_tr.arb b/packages/flutter_localizations/lib/src/l10n/material_tr.arb
index 9e41e77..5632770 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_tr.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_tr.arb
@@ -30,5 +30,8 @@
   "postMeridiemAbbreviation": "ÖS",
   "timePickerHourModeAnnouncement": "Saati seçin",
   "timePickerMinuteModeAnnouncement": "Dakikayı seçin",
+  "signedInLabel": "Yetkili",
+  "hideAccountsLabel": "Hesapları gizle",
+  "showAccountsLabel": "Hesapları göster",
   "modalBarrierDismissLabel": "Reddet"
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ur.arb b/packages/flutter_localizations/lib/src/l10n/material_ur.arb
index 290ab75..0875ad3 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ur.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ur.arb
@@ -30,5 +30,8 @@
   "postMeridiemAbbreviation": "PM",
   "timePickerHourModeAnnouncement": "گھنٹے منتخب کریں",
   "timePickerMinuteModeAnnouncement": "منٹ منتخب کریں",
+  "signedInLabel": "سائن ان",
+  "hideAccountsLabel": "اکاؤنٹس چھپائیں",
+  "showAccountsLabel": "اکاؤنٹس دکھائیں",
   "modalBarrierDismissLabel": "برطرف"
 }
diff --git a/packages/flutter_localizations/lib/src/l10n/material_zh.arb b/packages/flutter_localizations/lib/src/l10n/material_zh.arb
index 308a31e..19f2715 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_zh.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_zh.arb
@@ -30,5 +30,8 @@
   "postMeridiemAbbreviation": "下午",
   "timePickerHourModeAnnouncement": "选择小时",
   "timePickerMinuteModeAnnouncement": "选择分钟",
+  "signedInLabel": "登录",
+  "hideAccountsLabel": "隐藏帐户",
+  "showAccountsLabel": "显示帐户",
   "modalBarrierDismissLabel": "关闭"
 }
diff --git a/packages/flutter_localizations/lib/src/material_localizations.dart b/packages/flutter_localizations/lib/src/material_localizations.dart
index 11667ab..095422b 100644
--- a/packages/flutter_localizations/lib/src/material_localizations.dart
+++ b/packages/flutter_localizations/lib/src/material_localizations.dart
@@ -334,6 +334,15 @@
   @override
   String get modalBarrierDismissLabel => _translationBundle.modalBarrierDismissLabel;
 
+  @override
+  String get signedInLabel => _translationBundle.signedInLabel;
+
+  @override
+  String get hideAccountsLabel => _translationBundle.hideAccountsLabel;
+
+  @override
+  String get showAccountsLabel => _translationBundle.showAccountsLabel;
+
   /// The [TimeOfDayFormat] corresponding to one of the following supported
   /// patterns:
   ///