diff --git a/dev/integration_tests/android_semantics_testing/lib/main.dart b/dev/integration_tests/android_semantics_testing/lib/main.dart index 12afeada564..3e8002ba233 100644 --- a/dev/integration_tests/android_semantics_testing/lib/main.dart +++ b/dev/integration_tests/android_semantics_testing/lib/main.dart @@ -23,11 +23,11 @@ void main() { const MethodChannel kSemanticsChannel = MethodChannel('semantics'); -Future dataHandler(String? message) async { - if (message != null && message.contains('getSemanticsNode')) { +Future dataHandler(String message) async { + if (message.contains('getSemanticsNode')) { final Completer completer = Completer(); final int id = int.tryParse(message.split('#')[1]) ?? 0; - Future completeSemantics([Object? _]) async { + Future completeSemantics([Object _]) async { final dynamic result = await kSemanticsChannel.invokeMethod('getSemanticsNode', { 'id': id, }); @@ -40,10 +40,10 @@ Future dataHandler(String? message) async { } return completer.future; } - if (message != null && message.contains('setClipboard')) { + if (message.contains('setClipboard')) { final Completer completer = Completer(); final String str = message.split('#')[1]; - Future completeSetClipboard([Object? _]) async { + Future completeSetClipboard([Object _]) async { await kSemanticsChannel.invokeMethod('setClipboard', { 'message': str, }); @@ -67,7 +67,7 @@ Map routes = { }; class TestApp extends StatelessWidget { - const TestApp({super.key}); + const TestApp({Key key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/dev/integration_tests/android_semantics_testing/lib/src/common.dart b/dev/integration_tests/android_semantics_testing/lib/src/common.dart index 205a0a49e48..9305855f495 100644 --- a/dev/integration_tests/android_semantics_testing/lib/src/common.dart +++ b/dev/integration_tests/android_semantics_testing/lib/src/common.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// ignore_for_file: avoid_dynamic_calls - import 'dart:convert'; import 'package:meta/meta.dart'; @@ -55,13 +53,13 @@ class AndroidSemanticsNode { /// ] /// } factory AndroidSemanticsNode.deserialize(String value) { - return AndroidSemanticsNode._(json.decode(value)); + return AndroidSemanticsNode._(json.decode(value) as Map); } - final dynamic _values; + final Map _values; final List _children = []; - dynamic get _flags => _values['flags']; + Map get _flags => _values['flags'] as Map; /// The text value of the semantics node. /// @@ -134,12 +132,13 @@ class AndroidSemanticsNode { /// Gets a [Rect] which defines the position and size of the semantics node. Rect getRect() { - final dynamic rawRect = _values['rect']; + final Map rawRect = _values['rect'] as Map; + final Map rect = rawRect.cast(); return Rect.fromLTRB( - (rawRect['left']! as int).toDouble(), - (rawRect['top']! as int).toDouble(), - (rawRect['right']! as int).toDouble(), - (rawRect['bottom']! as int).toDouble(), + rect['left'].toDouble(), + rect['top'].toDouble(), + rect['right'].toDouble(), + rect['bottom'].toDouble(), ); } @@ -151,7 +150,7 @@ class AndroidSemanticsNode { /// Gets a list of [AndroidSemanticsActions] which are defined for the node. List getActions() => [ - for (final int id in (_values['actions']! as List).cast()) AndroidSemanticsAction.deserialize(id)!, + for (final int id in (_values['actions'] as List).cast()) AndroidSemanticsAction.deserialize(id), ]; @override diff --git a/dev/integration_tests/android_semantics_testing/lib/src/constants.dart b/dev/integration_tests/android_semantics_testing/lib/src/constants.dart index ef8a863d9eb..22f75bc7bd6 100644 --- a/dev/integration_tests/android_semantics_testing/lib/src/constants.dart +++ b/dev/integration_tests/android_semantics_testing/lib/src/constants.dart @@ -168,7 +168,7 @@ class AndroidSemanticsAction { case _kSetText: return 'AndroidSemanticsAction.setText'; default: - throw UnimplementedError(); + return null; } } @@ -211,7 +211,7 @@ class AndroidSemanticsAction { /// Creates a new [AndroidSemanticsAction] from an integer `value`. /// /// Returns `null` if the id is not a known Android accessibility action. - static AndroidSemanticsAction? deserialize(int value) { + static AndroidSemanticsAction deserialize(int value) { return _kActionById[value]; } } diff --git a/dev/integration_tests/android_semantics_testing/lib/src/matcher.dart b/dev/integration_tests/android_semantics_testing/lib/src/matcher.dart index 37155e668ac..ea36302266a 100644 --- a/dev/integration_tests/android_semantics_testing/lib/src/matcher.dart +++ b/dev/integration_tests/android_semantics_testing/lib/src/matcher.dart @@ -18,24 +18,24 @@ import 'constants.dart'; /// the Android accessibility bridge, and not the semantics object created by /// the Flutter framework. Matcher hasAndroidSemantics({ - String? text, - String? contentDescription, - String? className, - int? id, - Rect? rect, - Size? size, - List? actions, - List? ignoredActions, - List? children, - bool? isChecked, - bool? isCheckable, - bool? isEditable, - bool? isEnabled, - bool? isFocusable, - bool? isFocused, - bool? isHeading, - bool? isPassword, - bool? isLongClickable, + String text, + String contentDescription, + String className, + int id, + Rect rect, + Size size, + List actions, + List ignoredActions, + List children, + bool isChecked, + bool isCheckable, + bool isEditable, + bool isEnabled, + bool isFocusable, + bool isFocused, + bool isHeading, + bool isPassword, + bool isLongClickable, }) { return _AndroidSemanticsMatcher( text: text, @@ -79,23 +79,23 @@ class _AndroidSemanticsMatcher extends Matcher { this.isLongClickable, }); - final String? text; - final String? className; - final String? contentDescription; - final int? id; - final List? actions; - final List? ignoredActions; - final Rect? rect; - final Size? size; - final bool? isChecked; - final bool? isCheckable; - final bool? isEditable; - final bool? isEnabled; - final bool? isFocusable; - final bool? isFocused; - final bool? isHeading; - final bool? isPassword; - final bool? isLongClickable; + final String text; + final String className; + final String contentDescription; + final int id; + final List actions; + final List ignoredActions; + final Rect rect; + final Size size; + final bool isChecked; + final bool isCheckable; + final bool isEditable; + final bool isEnabled; + final bool isFocusable; + final bool isFocused; + final bool isHeading; + final bool isPassword; + final bool isLongClickable; @override Description describe(Description description) { @@ -149,7 +149,7 @@ class _AndroidSemanticsMatcher extends Matcher { } @override - bool matches(covariant AndroidSemanticsNode item, Map matchState) { + bool matches(covariant AndroidSemanticsNode item, Map matchState) { if (text != null && text != item.text) { return _failWithMessage('Expected text: $text', matchState); } @@ -170,13 +170,13 @@ class _AndroidSemanticsMatcher extends Matcher { } if (actions != null) { final List itemActions = item.getActions(); - if (!unorderedEquals(actions!).matches(itemActions, matchState)) { - final List actionsString = actions!.map((AndroidSemanticsAction action) => action.toString()).toList()..sort(); + if (!unorderedEquals(actions).matches(itemActions, matchState)) { + final List actionsString = actions.map((AndroidSemanticsAction action) => action.toString()).toList()..sort(); final List itemActionsString = itemActions.map((AndroidSemanticsAction action) => action.toString()).toList()..sort(); - final Set unexpected = itemActions.toSet().difference(actions!.toSet()); + final Set unexpected = itemActions.toSet().difference(actions.toSet()); final Set unexpectedInString = itemActionsString.toSet().difference(actionsString.toSet()); final Set missingInString = actionsString.toSet().difference(itemActionsString.toSet()); - if (missingInString.isEmpty && ignoredActions != null && unexpected.every(ignoredActions!.contains)) { + if (missingInString.isEmpty && ignoredActions != null && unexpected.every(ignoredActions.contains)) { return true; } return _failWithMessage('Expected actions: $actionsString\nActual actions: $itemActionsString\nUnexpected: $unexpectedInString\nMissing: $missingInString', matchState); @@ -214,8 +214,8 @@ class _AndroidSemanticsMatcher extends Matcher { } @override - Description describeMismatch(dynamic item, Description mismatchDescription, - Map matchState, bool verbose) { + Description describeMismatch(Object item, Description mismatchDescription, + Map matchState, bool verbose) { return mismatchDescription.add(matchState['failure'] as String); } diff --git a/dev/integration_tests/android_semantics_testing/lib/src/tests/controls_page.dart b/dev/integration_tests/android_semantics_testing/lib/src/tests/controls_page.dart index fad7ff4ebaf..3d4cda7e572 100644 --- a/dev/integration_tests/android_semantics_testing/lib/src/tests/controls_page.dart +++ b/dev/integration_tests/android_semantics_testing/lib/src/tests/controls_page.dart @@ -9,7 +9,7 @@ export 'controls_constants.dart'; /// A test page with a checkbox, three radio buttons, and a switch. class SelectionControlsPage extends StatefulWidget { - const SelectionControlsPage({super.key}); + const SelectionControlsPage({Key key}) : super(key: key); @override State createState() => _SelectionControlsPageState(); @@ -28,15 +28,15 @@ class _SelectionControlsPageState extends State { bool _isLabeledOn = false; int _radio = 0; - void _updateCheckbox(bool? newValue) { + void _updateCheckbox(bool newValue) { setState(() { - _isChecked = newValue!; + _isChecked = newValue; }); } - void _updateRadio(int? newValue) { + void _updateRadio(int newValue) { setState(() { - _radio = newValue!; + _radio = newValue; }); } diff --git a/dev/integration_tests/android_semantics_testing/lib/src/tests/headings_page.dart b/dev/integration_tests/android_semantics_testing/lib/src/tests/headings_page.dart index a4ccf0b7489..b08ebdbbe41 100644 --- a/dev/integration_tests/android_semantics_testing/lib/src/tests/headings_page.dart +++ b/dev/integration_tests/android_semantics_testing/lib/src/tests/headings_page.dart @@ -9,7 +9,7 @@ export 'headings_constants.dart'; /// A test page with an app bar and some body text for testing heading flags. class HeadingsPage extends StatelessWidget { - const HeadingsPage({super.key}); + const HeadingsPage({Key key}) : super(key: key); static const ValueKey _appBarTitleKey = ValueKey(appBarTitleKeyValue); static const ValueKey _bodyTextKey = ValueKey(bodyTextKeyValue); diff --git a/dev/integration_tests/android_semantics_testing/lib/src/tests/popup_page.dart b/dev/integration_tests/android_semantics_testing/lib/src/tests/popup_page.dart index 3ede08eac3b..6f0b064fc02 100644 --- a/dev/integration_tests/android_semantics_testing/lib/src/tests/popup_page.dart +++ b/dev/integration_tests/android_semantics_testing/lib/src/tests/popup_page.dart @@ -10,7 +10,7 @@ export 'popup_constants.dart'; /// A page with a popup menu, a dropdown menu, and a modal alert. class PopupControlsPage extends StatefulWidget { - const PopupControlsPage({super.key}); + const PopupControlsPage({Key key}) : super(key: key); @override State createState() => _PopupControlsPageState(); @@ -60,9 +60,9 @@ class _PopupControlsPageState extends State { child: Text(item), ); }).toList(), - onChanged: (String? value) { + onChanged: (String value) { setState(() { - dropdownValue = value!; + dropdownValue = value; }); }, ), diff --git a/dev/integration_tests/android_semantics_testing/lib/src/tests/text_field_page.dart b/dev/integration_tests/android_semantics_testing/lib/src/tests/text_field_page.dart index fcd6368c0bc..20a22449aa2 100644 --- a/dev/integration_tests/android_semantics_testing/lib/src/tests/text_field_page.dart +++ b/dev/integration_tests/android_semantics_testing/lib/src/tests/text_field_page.dart @@ -10,7 +10,7 @@ export 'text_field_constants.dart'; /// A page with a normal text field and a password field. class TextFieldPage extends StatefulWidget { - const TextFieldPage({super.key}); + const TextFieldPage({Key key}) : super(key: key); @override State createState() => _TextFieldPageState(); diff --git a/dev/integration_tests/android_semantics_testing/pubspec.yaml b/dev/integration_tests/android_semantics_testing/pubspec.yaml index 417b4ce1abc..4801d409fc1 100644 --- a/dev/integration_tests/android_semantics_testing/pubspec.yaml +++ b/dev/integration_tests/android_semantics_testing/pubspec.yaml @@ -1,7 +1,7 @@ name: android_semantics_testing description: Integration testing library for Android semantics environment: - sdk: '>=2.17.0-0 <3.0.0' + sdk: '>=2.9.0 <3.0.0' dependencies: flutter: diff --git a/dev/integration_tests/android_semantics_testing/test_driver/main_test.dart b/dev/integration_tests/android_semantics_testing/test_driver/main_test.dart index df0f14f263d..e4faad917f1 100644 --- a/dev/integration_tests/android_semantics_testing/test_driver/main_test.dart +++ b/dev/integration_tests/android_semantics_testing/test_driver/main_test.dart @@ -20,7 +20,7 @@ const List ignoredAccessibilityFocusActions = getSemantics(SerializableFinder finder) async { final int id = await driver.getSemanticsId(finder); final String data = await driver.requestData('getSemanticsNode#$id'); @@ -38,7 +38,7 @@ void main() { } // The version of TalkBack running on the device. - Version? talkbackVersion; + Version talkbackVersion; Future getTalkbackVersion() async { final io.ProcessResult result = await io.Process.run(adbPath(), const [ @@ -51,7 +51,7 @@ void main() { throw Exception('Failed to get TalkBack version: ${result.stdout as String}\n${result.stderr as String}'); } final List lines = (result.stdout as String).split('\n'); - String? version; + String version; for (final String line in lines) { if (line.contains('versionName')) { version = line.replaceAll(RegExp(r'\s*versionName='), ''); @@ -64,14 +64,14 @@ void main() { // Android doesn't quite use semver, so convert the version string to semver form. final RegExp startVersion = RegExp(r'(?\d+)\.(?\d+)\.(?\d+)(\.(?\d+))?'); - final RegExpMatch? match = startVersion.firstMatch(version); + final RegExpMatch match = startVersion.firstMatch(version); if (match == null) { return Version(0, 0, 0); } return Version( - int.parse(match.namedGroup('major')!), - int.parse(match.namedGroup('minor')!), - int.parse(match.namedGroup('patch')!), + int.parse(match.namedGroup('major')), + int.parse(match.namedGroup('minor')), + int.parse(match.namedGroup('patch')), build: match.namedGroup('build'), ); } @@ -104,7 +104,7 @@ void main() { 'null', ]); await run.exitCode; - driver.close(); + driver?.close(); }); group('TextField', () {