
This auto-formats all *.dart files in the repository outside of the `engine` subdirectory and enforces that these files stay formatted with a presubmit check. **Reviewers:** Please carefully review all the commits except for the one titled "formatted". The "formatted" commit was auto-generated by running `dev/tools/format.sh -a -f`. The other commits were hand-crafted to prepare the repo for the formatting change. I recommend reviewing the commits one-by-one via the "Commits" tab and avoiding Github's "Files changed" tab as it will likely slow down your browser because of the size of this PR. --------- Co-authored-by: Kate Lovett <katelovett@google.com> Co-authored-by: LongCatIsLooong <31859944+LongCatIsLooong@users.noreply.github.com>
186 lines
5.9 KiB
Dart
186 lines
5.9 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'package:collection/collection.dart';
|
|
|
|
// Android MotionEvent actions for which a pointer index is encoded in the
|
|
// unmasked action code.
|
|
const List<int> kPointerActions = <int>[
|
|
0, // DOWN
|
|
1, // UP
|
|
5, // POINTER_DOWN
|
|
6, // POINTER_UP
|
|
];
|
|
|
|
const double kDoubleErrorMargin = 1e-4;
|
|
|
|
String diffMotionEvents(Map<String, dynamic> originalEvent, Map<String, dynamic> synthesizedEvent) {
|
|
final StringBuffer diff = StringBuffer();
|
|
|
|
diffMaps(
|
|
originalEvent,
|
|
synthesizedEvent,
|
|
diff,
|
|
excludeKeys: const <String>[
|
|
'pointerProperties', // Compared separately.
|
|
'pointerCoords', // Compared separately.
|
|
'source', // Unused by Flutter.
|
|
'deviceId', // Android documentation says that's an arbitrary number that shouldn't be depended on.
|
|
'action', // Compared separately.
|
|
'motionEventId', // TODO(kaushikiska): add support for motion event diffing, https://github.com/flutter/flutter/issues/61022.
|
|
],
|
|
);
|
|
|
|
diffActions(diff, originalEvent, synthesizedEvent);
|
|
diffPointerProperties(diff, originalEvent, synthesizedEvent);
|
|
diffPointerCoordsList(diff, originalEvent, synthesizedEvent);
|
|
|
|
return diff.toString();
|
|
}
|
|
|
|
void diffActions(
|
|
StringBuffer diffBuffer,
|
|
Map<String, dynamic> originalEvent,
|
|
Map<String, dynamic> synthesizedEvent,
|
|
) {
|
|
final int synthesizedActionMasked = getActionMasked(synthesizedEvent['action'] as int);
|
|
final int originalActionMasked = getActionMasked(originalEvent['action'] as int);
|
|
final String synthesizedActionName = getActionName(
|
|
synthesizedActionMasked,
|
|
synthesizedEvent['action'] as int,
|
|
);
|
|
final String originalActionName = getActionName(
|
|
originalActionMasked,
|
|
originalEvent['action'] as int,
|
|
);
|
|
|
|
if (synthesizedActionMasked != originalActionMasked) {
|
|
diffBuffer.write('action (expected: $originalActionName actual: $synthesizedActionName) ');
|
|
}
|
|
|
|
if (kPointerActions.contains(originalActionMasked) &&
|
|
originalActionMasked == synthesizedActionMasked) {
|
|
final int originalPointer = getPointerIdx(originalEvent['action'] as int);
|
|
final int synthesizedPointer = getPointerIdx(synthesizedEvent['action'] as int);
|
|
if (originalPointer != synthesizedPointer) {
|
|
diffBuffer.write(
|
|
'pointerIdx (expected: $originalPointer actual: $synthesizedPointer action: $originalActionName ',
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
void diffPointerProperties(
|
|
StringBuffer diffBuffer,
|
|
Map<String, dynamic> originalEvent,
|
|
Map<String, dynamic> synthesizedEvent,
|
|
) {
|
|
final List<Map<dynamic, dynamic>> expectedList =
|
|
(originalEvent['pointerProperties'] as List<dynamic>).cast<Map<dynamic, dynamic>>();
|
|
final List<Map<dynamic, dynamic>> actualList =
|
|
(synthesizedEvent['pointerProperties'] as List<dynamic>).cast<Map<dynamic, dynamic>>();
|
|
|
|
if (expectedList.length != actualList.length) {
|
|
diffBuffer.write(
|
|
'pointerProperties (actual length: ${actualList.length}, expected length: ${expectedList.length} ',
|
|
);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < expectedList.length; i++) {
|
|
final Map<String, dynamic> expected = expectedList[i].cast<String, dynamic>();
|
|
final Map<String, dynamic> actual = actualList[i].cast<String, dynamic>();
|
|
diffMaps(expected, actual, diffBuffer, messagePrefix: '[pointerProperty $i] ');
|
|
}
|
|
}
|
|
|
|
void diffPointerCoordsList(
|
|
StringBuffer diffBuffer,
|
|
Map<String, dynamic> originalEvent,
|
|
Map<String, dynamic> synthesizedEvent,
|
|
) {
|
|
final List<Map<dynamic, dynamic>> expectedList =
|
|
(originalEvent['pointerCoords'] as List<dynamic>).cast<Map<dynamic, dynamic>>();
|
|
final List<Map<dynamic, dynamic>> actualList =
|
|
(synthesizedEvent['pointerCoords'] as List<dynamic>).cast<Map<dynamic, dynamic>>();
|
|
|
|
if (expectedList.length != actualList.length) {
|
|
diffBuffer.write(
|
|
'pointerCoords (actual length: ${actualList.length}, expected length: ${expectedList.length} ',
|
|
);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < expectedList.length; i++) {
|
|
final Map<String, dynamic> expected = expectedList[i].cast<String, dynamic>();
|
|
final Map<String, dynamic> actual = actualList[i].cast<String, dynamic>();
|
|
diffPointerCoords(expected, actual, i, diffBuffer);
|
|
}
|
|
}
|
|
|
|
void diffPointerCoords(
|
|
Map<String, dynamic> expected,
|
|
Map<String, dynamic> actual,
|
|
int pointerIdx,
|
|
StringBuffer diffBuffer,
|
|
) {
|
|
diffMaps(expected, actual, diffBuffer, messagePrefix: '[pointerCoord $pointerIdx] ');
|
|
}
|
|
|
|
void diffMaps(
|
|
Map<String, dynamic> expected,
|
|
Map<String, dynamic> actual,
|
|
StringBuffer diffBuffer, {
|
|
List<String> excludeKeys = const <String>[],
|
|
String messagePrefix = '',
|
|
}) {
|
|
const IterableEquality<String> eq = IterableEquality<String>();
|
|
if (!eq.equals(expected.keys, actual.keys)) {
|
|
diffBuffer.write('${messagePrefix}keys (expected: ${expected.keys} actual: ${actual.keys} ');
|
|
return;
|
|
}
|
|
for (final String key in expected.keys) {
|
|
if (excludeKeys.contains(key)) {
|
|
continue;
|
|
}
|
|
if (doublesApproximatelyMatch(expected[key], actual[key])) {
|
|
continue;
|
|
}
|
|
|
|
if (expected[key] != actual[key]) {
|
|
diffBuffer.write('$messagePrefix$key (expected: ${expected[key]} actual: ${actual[key]}) ');
|
|
}
|
|
}
|
|
}
|
|
|
|
int getActionMasked(int action) => action & 0xff;
|
|
|
|
int getPointerIdx(int action) => (action >> 8) & 0xff;
|
|
|
|
String getActionName(int actionMasked, int action) {
|
|
const List<String> actionNames = <String>[
|
|
'DOWN',
|
|
'UP',
|
|
'MOVE',
|
|
'CANCEL',
|
|
'OUTSIDE',
|
|
'POINTER_DOWN',
|
|
'POINTER_UP',
|
|
'HOVER_MOVE',
|
|
'SCROLL',
|
|
'HOVER_ENTER',
|
|
'HOVER_EXIT',
|
|
'BUTTON_PRESS',
|
|
'BUTTON_RELEASE',
|
|
];
|
|
if (actionMasked < actionNames.length) {
|
|
return '${actionNames[actionMasked]}($action)';
|
|
} else {
|
|
return 'ACTION_$actionMasked';
|
|
}
|
|
}
|
|
|
|
bool doublesApproximatelyMatch(dynamic a, dynamic b) =>
|
|
a is double && b is double && (a - b).abs() < kDoubleErrorMargin;
|