/
magnusroot
/
flutter
Обзор
Документация
Войти
/
magnusroot
/
flutter
Код
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
dev/integration_tests/android_views/lib/motion_event_diff.dart
185 строк
6 KB
Kate Lovett
Modernize framework lints (#179089)
26 ноя 2025, 04:10
Не верифицирован
26 ноя 2025, 04:10
9d96df2
Код
Авторство
О чём код?
// 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 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 (var 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 (var 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 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 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;