Unverified Commit 852bfe2a authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Use `BindingBase.platformDispatcher` over `BindingBase.window` where possible (#99443)

parent 020bf31c
......@@ -509,12 +509,12 @@ abstract class BindingBase {
}
_postExtensionStateChangedEvent(
brightnessOverrideExtensionName,
(debugBrightnessOverride ?? window.platformBrightness).toString(),
(debugBrightnessOverride ?? platformDispatcher.platformBrightness).toString(),
);
await reassembleApplication();
}
return <String, dynamic>{
'value': (debugBrightnessOverride ?? window.platformBrightness).toString(),
'value': (debugBrightnessOverride ?? platformDispatcher.platformBrightness).toString(),
};
},
);
......
......@@ -258,7 +258,7 @@ mixin GestureBinding on BindingBase implements HitTestable, HitTestDispatcher, H
void initInstances() {
super.initInstances();
_instance = this;
window.onPointerDataPacket = _handlePointerDataPacket;
platformDispatcher.onPointerDataPacket = _handlePointerDataPacket;
}
/// The singleton instance of this object.
......
......@@ -22,7 +22,7 @@ class DeviceGestureSettings {
});
/// Create a new [DeviceGestureSettings] from the provided [window].
factory DeviceGestureSettings.fromWindow(ui.SingletonFlutterWindow window) {
factory DeviceGestureSettings.fromWindow(ui.FlutterView window) {
final double? physicalTouchSlop = window.viewConfiguration.gestureSettings.physicalTouchSlop;
return DeviceGestureSettings(
touchSlop: physicalTouchSlop == null ? null : physicalTouchSlop / window.devicePixelRatio
......
......@@ -32,7 +32,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture
onSemanticsOwnerCreated: _handleSemanticsOwnerCreated,
onSemanticsOwnerDisposed: _handleSemanticsOwnerDisposed,
);
window
platformDispatcher
..onMetricsChanged = handleMetricsChanged
..onTextScaleFactorChanged = handleTextScaleFactorChanged
..onPlatformBrightnessChanged = handlePlatformBrightnessChanged
......@@ -327,7 +327,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture
}
void _handleSemanticsEnabledChanged() {
setSemanticsEnabled(window.semanticsEnabled);
setSemanticsEnabled(platformDispatcher.semanticsEnabled);
}
/// Whether the render tree associated with this binding should produce a tree
......
......@@ -271,10 +271,10 @@ mixin SchedulerBinding on BindingBase {
void addTimingsCallback(TimingsCallback callback) {
_timingsCallbacks.add(callback);
if (_timingsCallbacks.length == 1) {
assert(window.onReportTimings == null);
window.onReportTimings = _executeTimingsCallbacks;
assert(platformDispatcher.onReportTimings == null);
platformDispatcher.onReportTimings = _executeTimingsCallbacks;
}
assert(window.onReportTimings == _executeTimingsCallbacks);
assert(platformDispatcher.onReportTimings == _executeTimingsCallbacks);
}
/// Removes a callback that was earlier added by [addTimingsCallback].
......@@ -282,7 +282,7 @@ mixin SchedulerBinding on BindingBase {
assert(_timingsCallbacks.contains(callback));
_timingsCallbacks.remove(callback);
if (_timingsCallbacks.isEmpty) {
window.onReportTimings = null;
platformDispatcher.onReportTimings = null;
}
}
......@@ -727,8 +727,8 @@ mixin SchedulerBinding on BindingBase {
/// [PlatformDispatcher.onDrawFrame] are registered.
@protected
void ensureFrameCallbacksRegistered() {
window.onBeginFrame ??= _handleBeginFrame;
window.onDrawFrame ??= _handleDrawFrame;
platformDispatcher.onBeginFrame ??= _handleBeginFrame;
platformDispatcher.onDrawFrame ??= _handleDrawFrame;
}
/// Schedules a new frame using [scheduleFrame] if this object is not
......@@ -793,7 +793,7 @@ mixin SchedulerBinding on BindingBase {
return true;
}());
ensureFrameCallbacksRegistered();
window.scheduleFrame();
platformDispatcher.scheduleFrame();
_hasScheduledFrame = true;
}
......@@ -825,7 +825,7 @@ mixin SchedulerBinding on BindingBase {
debugPrintStack(label: 'scheduleForcedFrame() called. Current phase is $schedulerPhase.');
return true;
}());
window.scheduleFrame();
platformDispatcher.scheduleFrame();
_hasScheduledFrame = true;
}
......
......@@ -17,7 +17,7 @@ mixin SemanticsBinding on BindingBase {
void initInstances() {
super.initInstances();
_instance = this;
_accessibilityFeatures = window.accessibilityFeatures;
_accessibilityFeatures = platformDispatcher.accessibilityFeatures;
}
/// The current [SemanticsBinding], if one has been created.
......@@ -33,7 +33,7 @@ mixin SemanticsBinding on BindingBase {
/// See [dart:ui.PlatformDispatcher.onAccessibilityFeaturesChanged].
@protected
void handleAccessibilityFeaturesChanged() {
_accessibilityFeatures = window.accessibilityFeatures;
_accessibilityFeatures = platformDispatcher.accessibilityFeatures;
}
/// Creates an empty semantics update builder.
......
......@@ -3046,7 +3046,7 @@ class SemanticsOwner extends ChangeNotifier {
final CustomSemanticsAction action = CustomSemanticsAction.getAction(actionId)!;
builder.updateCustomAction(id: actionId, label: action.label, hint: action.hint, overrideId: action.action?.index ?? -1);
}
SemanticsBinding.instance.window.updateSemantics(builder.build());
SemanticsBinding.instance.platformDispatcher.updateSemantics(builder.build());
notifyListeners();
}
......
......@@ -61,7 +61,7 @@ mixin ServicesBinding on BindingBase, SchedulerBinding {
void _initKeyboard() {
_keyboard = HardwareKeyboard();
_keyEventManager = KeyEventManager(_keyboard, RawKeyboard.instance);
window.onKeyData = _keyEventManager.handleKeyData;
platformDispatcher.onKeyData = _keyEventManager.handleKeyData;
SystemChannels.keyEvent.setMessageHandler(_keyEventManager.handleRawKeyMessage);
}
......@@ -225,11 +225,11 @@ mixin ServicesBinding on BindingBase, SchedulerBinding {
// App life cycle
/// Initializes the [lifecycleState] with the
/// [dart:ui.SingletonFlutterWindow.initialLifecycleState].
/// [dart:ui.PlatformDispatcher.initialLifecycleState].
///
/// Once the [lifecycleState] is populated through any means (including this
/// method), this method will do nothing. This is because the
/// [dart:ui.SingletonFlutterWindow.initialLifecycleState] may already be
/// [dart:ui.PlatformDispatcher.initialLifecycleState] may already be
/// stale and it no longer makes sense to use the initial state at dart vm
/// startup as the current state anymore.
///
......@@ -240,7 +240,7 @@ mixin ServicesBinding on BindingBase, SchedulerBinding {
if (lifecycleState != null) {
return;
}
final AppLifecycleState? state = _parseAppLifecycleMessage(window.initialLifecycleState);
final AppLifecycleState? state = _parseAppLifecycleMessage(platformDispatcher.initialLifecycleState);
if (state != null) {
handleAppLifecycleStateChanged(state);
}
......
......@@ -1272,15 +1272,15 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
// If window.defaultRouteName isn't '/', we should assume it was set
// intentionally via `setInitialRoute`, and should override whatever is in
// [widget.initialRoute].
String get _initialRouteName => WidgetsBinding.instance.window.defaultRouteName != Navigator.defaultRouteName
? WidgetsBinding.instance.window.defaultRouteName
: widget.initialRoute ?? WidgetsBinding.instance.window.defaultRouteName;
String get _initialRouteName => WidgetsBinding.instance.platformDispatcher.defaultRouteName != Navigator.defaultRouteName
? WidgetsBinding.instance.platformDispatcher.defaultRouteName
: widget.initialRoute ?? WidgetsBinding.instance.platformDispatcher.defaultRouteName;
@override
void initState() {
super.initState();
_updateRouting();
_locale = _resolveLocales(WidgetsBinding.instance.window.locales, widget.supportedLocales);
_locale = _resolveLocales(WidgetsBinding.instance.platformDispatcher.locales, widget.supportedLocales);
WidgetsBinding.instance.addObserver(this);
}
......
......@@ -287,8 +287,8 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
// properly setup the [defaultBinaryMessenger] instance.
_buildOwner = BuildOwner();
buildOwner!.onBuildScheduled = _handleBuildScheduled;
window.onLocaleChanged = handleLocaleChanged;
window.onAccessibilityFeaturesChanged = handleAccessibilityFeaturesChanged;
platformDispatcher.onLocaleChanged = handleLocaleChanged;
platformDispatcher.onAccessibilityFeaturesChanged = handleAccessibilityFeaturesChanged;
SystemChannels.navigation.setMethodCallHandler(_handleNavigationInvocation);
assert(() {
FlutterErrorDetails.propertiesTransformers.add(debugTransformDebugCreator);
......@@ -590,7 +590,7 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
@protected
@mustCallSuper
void handleLocaleChanged() {
dispatchLocalesChanged(window.locales);
dispatchLocalesChanged(platformDispatcher.locales);
}
/// Notify all the observers that the locale has changed (using
......@@ -1004,7 +1004,7 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
/// method again with the matched locale of the first call omitted from
/// `supportedLocales`.
Locale? computePlatformResolvedLocale(List<Locale> supportedLocales) {
return window.computePlatformResolvedLocale(supportedLocales);
return platformDispatcher.computePlatformResolvedLocale(supportedLocales);
}
}
......
......@@ -1943,7 +1943,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
final bool revealObscuredInput = _hasInputConnection
&& widget.obscureText
&& WidgetsBinding.instance.window.brieflyShowPassword
&& WidgetsBinding.instance.platformDispatcher.brieflyShowPassword
&& value.text.length == _value.text.length + 1;
_obscureShowCharTicksPending = revealObscuredInput ? _kObscureShowLatestCharCursorTicks : 0;
......@@ -2658,7 +2658,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
if (_obscureShowCharTicksPending > 0) {
setState(() {
_obscureShowCharTicksPending = WidgetsBinding.instance.window.brieflyShowPassword
_obscureShowCharTicksPending = WidgetsBinding.instance.platformDispatcher.brieflyShowPassword
? _obscureShowCharTicksPending - 1
: 0;
});
......@@ -3335,7 +3335,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
const Set<TargetPlatform> mobilePlatforms = <TargetPlatform> {
TargetPlatform.android, TargetPlatform.iOS, TargetPlatform.fuchsia,
};
final bool breiflyShowPassword = WidgetsBinding.instance.window.brieflyShowPassword
final bool breiflyShowPassword = WidgetsBinding.instance.platformDispatcher.brieflyShowPassword
&& mobilePlatforms.contains(defaultTargetPlatform);
if (breiflyShowPassword) {
final int? o = _obscureShowCharTicksPending > 0 ? _obscureLatestCharIndex : null;
......
......@@ -134,21 +134,21 @@ class MediaQueryData {
/// window's metrics change. For example, see
/// [WidgetsBindingObserver.didChangeMetrics] or
/// [dart:ui.PlatformDispatcher.onMetricsChanged].
MediaQueryData.fromWindow(ui.SingletonFlutterWindow window)
MediaQueryData.fromWindow(ui.FlutterView window)
: size = window.physicalSize / window.devicePixelRatio,
devicePixelRatio = window.devicePixelRatio,
textScaleFactor = window.textScaleFactor,
platformBrightness = window.platformBrightness,
textScaleFactor = window.platformDispatcher.textScaleFactor,
platformBrightness = window.platformDispatcher.platformBrightness,
padding = EdgeInsets.fromWindowPadding(window.padding, window.devicePixelRatio),
viewPadding = EdgeInsets.fromWindowPadding(window.viewPadding, window.devicePixelRatio),
viewInsets = EdgeInsets.fromWindowPadding(window.viewInsets, window.devicePixelRatio),
systemGestureInsets = EdgeInsets.fromWindowPadding(window.systemGestureInsets, window.devicePixelRatio),
accessibleNavigation = window.accessibilityFeatures.accessibleNavigation,
invertColors = window.accessibilityFeatures.invertColors,
disableAnimations = window.accessibilityFeatures.disableAnimations,
boldText = window.accessibilityFeatures.boldText,
highContrast = window.accessibilityFeatures.highContrast,
alwaysUse24HourFormat = window.alwaysUse24HourFormat,
accessibleNavigation = window.platformDispatcher.accessibilityFeatures.accessibleNavigation,
invertColors = window.platformDispatcher.accessibilityFeatures.invertColors,
disableAnimations = window.platformDispatcher.accessibilityFeatures.disableAnimations,
boldText = window.platformDispatcher.accessibilityFeatures.boldText,
highContrast = window.platformDispatcher.accessibilityFeatures.highContrast,
alwaysUse24HourFormat = window.platformDispatcher.alwaysUse24HourFormat,
navigationMode = NavigationMode.traditional,
gestureSettings = DeviceGestureSettings.fromWindow(window),
displayFeatures = window.displayFeatures;
......
......@@ -1368,7 +1368,7 @@ class PlatformRouteInformationProvider extends RouteInformationProvider with Wid
RouteInformation get value => _value;
RouteInformation _value;
RouteInformation _valueInEngine = RouteInformation(location: WidgetsBinding.instance.window.defaultRouteName);
RouteInformation _valueInEngine = RouteInformation(location: WidgetsBinding.instance.platformDispatcher.defaultRouteName);
void _platformReportsNewRouteInformation(RouteInformation routeInformation) {
if (_value == routeInformation)
......
......@@ -442,8 +442,8 @@ void main() {
expect(dependentBuildCount, equals(2));
// didChangeTextScaleFactor
tester.binding.window.textScaleFactorTestValue = 42;
addTearDown(tester.binding.window.clearTextScaleFactorTestValue);
tester.binding.platformDispatcher.textScaleFactorTestValue = 42;
addTearDown(tester.binding.platformDispatcher.clearTextScaleFactorTestValue);
await tester.pump();
......@@ -451,8 +451,8 @@ void main() {
expect(dependentBuildCount, equals(3));
// didChangePlatformBrightness
tester.binding.window.platformBrightnessTestValue = Brightness.dark;
addTearDown(tester.binding.window.clearPlatformBrightnessTestValue);
tester.binding.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
addTearDown(tester.binding.platformDispatcher.clearPlatformBrightnessTestValue);
await tester.pump();
......@@ -460,8 +460,8 @@ void main() {
expect(dependentBuildCount, equals(4));
// didChangeAccessibilityFeatures
tester.binding.window.accessibilityFeaturesTestValue = FakeAccessibilityFeatures.allOn;
addTearDown(tester.binding.window.clearAccessibilityFeaturesTestValue);
tester.binding.platformDispatcher.accessibilityFeaturesTestValue = FakeAccessibilityFeatures.allOn;
addTearDown(tester.binding.platformDispatcher.clearAccessibilityFeaturesTestValue);
await tester.pump();
......@@ -526,7 +526,7 @@ void main() {
testWidgets('MaterialApp uses regular theme when themeMode is light', (WidgetTester tester) async {
// Mock the Window to explicitly report a light platformBrightness.
tester.binding.window.platformBrightnessTestValue = Brightness.light;
tester.binding.platformDispatcher.platformBrightnessTestValue = Brightness.light;
late ThemeData appliedTheme;
await tester.pumpWidget(
......@@ -549,7 +549,7 @@ void main() {
expect(appliedTheme.brightness, Brightness.light);
// Mock the Window to explicitly report a dark platformBrightness.
tester.binding.window.platformBrightnessTestValue = Brightness.dark;
tester.binding.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
......@@ -572,7 +572,7 @@ void main() {
testWidgets('MaterialApp uses darkTheme when themeMode is dark', (WidgetTester tester) async {
// Mock the Window to explicitly report a light platformBrightness.
tester.binding.window.platformBrightnessTestValue = Brightness.light;
tester.binding.platformDispatcher.platformBrightnessTestValue = Brightness.light;
late ThemeData appliedTheme;
await tester.pumpWidget(
......@@ -595,7 +595,7 @@ void main() {
expect(appliedTheme.brightness, Brightness.dark);
// Mock the Window to explicitly report a dark platformBrightness.
tester.binding.window.platformBrightnessTestValue = Brightness.dark;
tester.binding.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
......@@ -619,7 +619,7 @@ void main() {
testWidgets('MaterialApp uses regular theme when themeMode is system and platformBrightness is light', (WidgetTester tester) async {
// Mock the Window to explicitly report a light platformBrightness.
final TestWidgetsFlutterBinding binding = tester.binding;
binding.window.platformBrightnessTestValue = Brightness.light;
binding.platformDispatcher.platformBrightnessTestValue = Brightness.light;
late ThemeData appliedTheme;
......@@ -645,7 +645,7 @@ void main() {
testWidgets('MaterialApp uses darkTheme when themeMode is system and platformBrightness is dark', (WidgetTester tester) async {
// Mock the Window to explicitly report a dark platformBrightness.
tester.binding.window.platformBrightnessTestValue = Brightness.dark;
tester.binding.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
late ThemeData appliedTheme;
await tester.pumpWidget(
......@@ -670,7 +670,7 @@ void main() {
testWidgets('MaterialApp uses light theme when platformBrightness is dark but no dark theme is provided', (WidgetTester tester) async {
// Mock the Window to explicitly report a dark platformBrightness.
final TestWidgetsFlutterBinding binding = tester.binding;
binding.window.platformBrightnessTestValue = Brightness.dark;
binding.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
late ThemeData appliedTheme;
......@@ -694,7 +694,7 @@ void main() {
testWidgets('MaterialApp uses fallback light theme when platformBrightness is dark but no theme is provided at all', (WidgetTester tester) async {
// Mock the Window to explicitly report a dark platformBrightness.
final TestWidgetsFlutterBinding binding = tester.binding;
binding.window.platformBrightnessTestValue = Brightness.dark;
binding.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
late ThemeData appliedTheme;
......@@ -715,7 +715,7 @@ void main() {
testWidgets('MaterialApp uses fallback light theme when platformBrightness is light and a dark theme is provided', (WidgetTester tester) async {
// Mock the Window to explicitly report a dark platformBrightness.
final TestWidgetsFlutterBinding binding = tester.binding;
binding.window.platformBrightnessTestValue = Brightness.light;
binding.platformDispatcher.platformBrightnessTestValue = Brightness.light;
late ThemeData appliedTheme;
......@@ -739,7 +739,7 @@ void main() {
testWidgets('MaterialApp uses dark theme when platformBrightness is dark', (WidgetTester tester) async {
// Mock the Window to explicitly report a dark platformBrightness.
final TestWidgetsFlutterBinding binding = tester.binding;
binding.window.platformBrightnessTestValue = Brightness.dark;
binding.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
late ThemeData appliedTheme;
......@@ -764,8 +764,8 @@ void main() {
});
testWidgets('MaterialApp uses high contrast theme when appropriate', (WidgetTester tester) async {
tester.binding.window.platformBrightnessTestValue = Brightness.light;
tester.binding.window.accessibilityFeaturesTestValue = FakeAccessibilityFeatures.allOn;
tester.binding.platformDispatcher.platformBrightnessTestValue = Brightness.light;
tester.binding.platformDispatcher.accessibilityFeaturesTestValue = FakeAccessibilityFeatures.allOn;
late ThemeData appliedTheme;
......@@ -787,12 +787,12 @@ void main() {
);
expect(appliedTheme.primaryColor, Colors.blue);
tester.binding.window.clearAccessibilityFeaturesTestValue();
tester.binding.platformDispatcher.clearAccessibilityFeaturesTestValue();
});
testWidgets('MaterialApp uses high contrast dark theme when appropriate', (WidgetTester tester) async {
tester.binding.window.platformBrightnessTestValue = Brightness.dark;
tester.binding.window.accessibilityFeaturesTestValue = FakeAccessibilityFeatures.allOn;
tester.binding.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
tester.binding.platformDispatcher.accessibilityFeaturesTestValue = FakeAccessibilityFeatures.allOn;
late ThemeData appliedTheme;
......@@ -820,12 +820,12 @@ void main() {
);
expect(appliedTheme.primaryColor, Colors.green);
tester.binding.window.clearAccessibilityFeaturesTestValue();
tester.binding.platformDispatcher.clearAccessibilityFeaturesTestValue();
});
testWidgets('MaterialApp uses dark theme when no high contrast dark theme is provided', (WidgetTester tester) async {
tester.binding.window.platformBrightnessTestValue = Brightness.dark;
tester.binding.window.accessibilityFeaturesTestValue = FakeAccessibilityFeatures.allOn;
tester.binding.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
tester.binding.platformDispatcher.accessibilityFeaturesTestValue = FakeAccessibilityFeatures.allOn;
late ThemeData appliedTheme;
......@@ -847,14 +847,14 @@ void main() {
);
expect(appliedTheme.primaryColor, Colors.lightGreen);
tester.binding.window.clearAccessibilityFeaturesTestValue();
tester.binding.window.clearPlatformBrightnessTestValue();
tester.binding.platformDispatcher.clearAccessibilityFeaturesTestValue();
tester.binding.platformDispatcher.clearPlatformBrightnessTestValue();
});
testWidgets('MaterialApp switches themes when the Window platformBrightness changes.', (WidgetTester tester) async {
// Mock the Window to explicitly report a light platformBrightness.
final TestWidgetsFlutterBinding binding = tester.binding;
binding.window.platformBrightnessTestValue = Brightness.light;
binding.platformDispatcher.platformBrightnessTestValue = Brightness.light;
ThemeData? themeBeforeBrightnessChange;
ThemeData? themeAfterBrightnessChange;
......@@ -882,7 +882,7 @@ void main() {
// Switch the platformBrightness from light to dark and pump the widget tree
// to process changes.
binding.window.platformBrightnessTestValue = Brightness.dark;
binding.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
await tester.pumpAndSettle();
expect(themeBeforeBrightnessChange!.brightness, Brightness.light);
......
......@@ -272,7 +272,7 @@ void main() {
expect(lightMaterial.color, lightBackgroundColor);
// Simulate the user changing to dark theme
tester.binding.window.platformBrightnessTestValue = Brightness.dark;
tester.binding.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
await tester.pumpAndSettle();
final Material darkMaterial = tester.widget<Material>(
......
......@@ -95,7 +95,6 @@ class TestBindingBase implements BindingBase {
}
class TestPaintingBinding extends TestBindingBase with SchedulerBinding, ServicesBinding, PaintingBinding {
@override
final FakeImageCache imageCache = FakeImageCache();
......
......@@ -13,7 +13,7 @@ void main() {
// Mock the Window to provide paused as the AppLifecycleState
final TestWidgetsFlutterBinding binding = tester.binding;
// Use paused as the initial state.
binding.window.initialLifecycleStateTestValue = 'AppLifecycleState.paused';
binding.platformDispatcher.initialLifecycleStateTestValue = 'AppLifecycleState.paused';
binding.readTestInitialLifecycleStateFromNativeWindow(); // Re-attempt the initialization.
// The lifecycleState should now be the state we passed above,
......
......@@ -22,7 +22,7 @@ void main() {
binding.drawFrame();
// Simulates the engine again.
binding.window.onReportTimings!(<FrameTiming>[]);
binding.platformDispatcher.onReportTimings!(<FrameTiming>[]);
expect(developer.getCurrentTag().label, equals('Default'));
});
......
......@@ -19,14 +19,14 @@ void main() {
// Simulates the engine completing a frame render to trigger the
// appropriate callback setting [WidgetBinding.firstFrameRasterized].
binding.window.onReportTimings!(<FrameTiming>[]);
binding.platformDispatcher.onReportTimings!(<FrameTiming>[]);
expect(binding.firstFrameRasterized, isFalse);
binding.allowFirstFrame();
fakeAsync.flushTimers();
// Simulates the engine again.
binding.window.onReportTimings!(<FrameTiming>[]);
binding.platformDispatcher.onReportTimings!(<FrameTiming>[]);
expect(binding.firstFrameRasterized, isTrue);
});
});
......
......@@ -3685,9 +3685,9 @@ void main() {
await tester.enterText(find.byType(EditableText), 'AAA');
await tester.pump();
tester.binding.window.brieflyShowPasswordTestValue = false;
tester.binding.platformDispatcher.brieflyShowPasswordTestValue = false;
addTearDown(() {
tester.binding.window.brieflyShowPasswordTestValue = true;
tester.binding.platformDispatcher.brieflyShowPasswordTestValue = true;
});
expect((findRenderEditable(tester).text! as TextSpan).text, '••A');
await tester.pump(const Duration(milliseconds: 500));
......
......@@ -160,6 +160,9 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
TestWindow get window => _window;
final TestWindow _window;
@override
TestPlatformDispatcher get platformDispatcher => _window.platformDispatcher;
@override
TestRestorationManager get restorationManager {
_restorationManager ??= createRestorationManager();
......@@ -1112,8 +1115,8 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
@override
void ensureFrameCallbacksRegistered() {
// Leave PlatformDispatcher alone, do nothing.
assert(window.onDrawFrame == null);
assert(window.onBeginFrame == null);
assert(platformDispatcher.onDrawFrame == null);
assert(platformDispatcher.onBeginFrame == null);
}
@override
......@@ -1550,7 +1553,7 @@ class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
_pendingFrame = null;
_expectingFrame = false;
} else if (framePolicy != LiveTestWidgetsFlutterBindingFramePolicy.benchmark) {
window.scheduleFrame();
platformDispatcher.scheduleFrame();
}
}
......
......@@ -46,16 +46,26 @@ import 'package:flutter/foundation.dart';
///
/// To clear all fake test values in a [TestWindow], consider using
/// [clearAllTestValues()].
///
/// See also:
///
/// * [TestPlatformDispatcher], which wraps a [PlatformDispatcher] for
/// testing purposes and is used by the [platformDispatcher] property of
/// this class.
class TestWindow implements ui.SingletonFlutterWindow {
/// Constructs a [TestWindow] that defers all behavior to the given
/// [dart:ui.SingletonFlutterWindow] unless explicitly overridden for test purposes.
TestWindow({
required ui.SingletonFlutterWindow window,
}) : _window = window;
}) : _window = window,
platformDispatcher = TestPlatformDispatcher(platformDispatcher: window.platformDispatcher);
/// The [dart:ui.SingletonFlutterWindow] that is wrapped by this [TestWindow].
final ui.SingletonFlutterWindow _window;
@override
final TestPlatformDispatcher platformDispatcher;
@override
double get devicePixelRatio => _devicePixelRatio ?? _window.devicePixelRatio;
double? _devicePixelRatio;
......@@ -170,31 +180,41 @@ class TestWindow implements ui.SingletonFlutterWindow {
}
@override
ui.Locale get locale => _localeTestValue ?? platformDispatcher.locale;
ui.Locale? _localeTestValue;
ui.Locale get locale => platformDispatcher.locale;
/// Hides the real locale and reports the given [localeTestValue] instead.
@Deprecated(
'Use platformDispatcher.localeTestValue instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
set localeTestValue(ui.Locale localeTestValue) { // ignore: avoid_setters_without_getters
_localeTestValue = localeTestValue;
onLocaleChanged?.call();
platformDispatcher.localeTestValue = localeTestValue;
}
@Deprecated(
'Use platformDispatcher.clearLocaleTestValue() instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
/// Deletes any existing test locale and returns to using the real locale.
void clearLocaleTestValue() {
_localeTestValue = null;
onLocaleChanged?.call();
platformDispatcher.clearLocaleTestValue();
}
@override
List<ui.Locale> get locales => _localesTestValue ?? platformDispatcher.locales;
List<ui.Locale>? _localesTestValue;
List<ui.Locale> get locales => platformDispatcher.locales;
/// Hides the real locales and reports the given [localesTestValue] instead.
@Deprecated(
'Use platformDispatcher.localesTestValue instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
set localesTestValue(List<ui.Locale> localesTestValue) { // ignore: avoid_setters_without_getters
_localesTestValue = localesTestValue;
onLocaleChanged?.call();
platformDispatcher.localesTestValue = localesTestValue;
}
/// Deletes any existing test locales and returns to using the real locales.
@Deprecated(
'Use platformDispatcher.clearLocalesTestValue() instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
void clearLocalesTestValue() {
_localesTestValue = null;
onLocaleChanged?.call();
platformDispatcher.clearLocalesTestValue();
}
@override
......@@ -205,32 +225,39 @@ class TestWindow implements ui.SingletonFlutterWindow {
}
@override
String get initialLifecycleState => _initialLifecycleStateTestValue;
String _initialLifecycleStateTestValue = '';
String get initialLifecycleState => platformDispatcher.initialLifecycleState;
/// Sets a faked initialLifecycleState for testing.
@Deprecated(
'Use platformDispatcher.initialLifecycleStateTestValue instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
set initialLifecycleStateTestValue(String state) { // ignore: avoid_setters_without_getters
_initialLifecycleStateTestValue = state;
platformDispatcher.initialLifecycleStateTestValue = state;
}
@override
double get textScaleFactor => _textScaleFactorTestValue ?? platformDispatcher.textScaleFactor;
double? _textScaleFactorTestValue;
double get textScaleFactor => platformDispatcher.textScaleFactor;
/// Hides the real text scale factor and reports the given
/// [textScaleFactorTestValue] instead.
@Deprecated(
'Use platformDispatcher.textScaleFactorTestValue instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
set textScaleFactorTestValue(double textScaleFactorTestValue) { // ignore: avoid_setters_without_getters
_textScaleFactorTestValue = textScaleFactorTestValue;
onTextScaleFactorChanged?.call();
platformDispatcher.textScaleFactorTestValue = textScaleFactorTestValue;
}
/// Deletes any existing test text scale factor and returns to using the real
/// text scale factor.
@Deprecated(
'Use platformDispatcher.clearTextScaleFactorTestValue() instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
void clearTextScaleFactorTestValue() {
_textScaleFactorTestValue = null;
onTextScaleFactorChanged?.call();
platformDispatcher.clearTextScaleFactorTestValue();
}
@override
ui.Brightness get platformBrightness => _platformBrightnessTestValue ?? platformDispatcher.platformBrightness;
ui.Brightness? _platformBrightnessTestValue;
ui.Brightness get platformBrightness => platformDispatcher.platformBrightness;
@override
ui.VoidCallback? get onPlatformBrightnessChanged => platformDispatcher.onPlatformBrightnessChanged;
@override
......@@ -239,29 +266,42 @@ class TestWindow implements ui.SingletonFlutterWindow {
}
/// Hides the real text scale factor and reports the given
/// [platformBrightnessTestValue] instead.
@Deprecated(
'Use platformDispatcher.platformBrightnessTestValue instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
set platformBrightnessTestValue(ui.Brightness platformBrightnessTestValue) { // ignore: avoid_setters_without_getters
_platformBrightnessTestValue = platformBrightnessTestValue;
onPlatformBrightnessChanged?.call();
platformDispatcher.platformBrightnessTestValue = platformBrightnessTestValue;
}
/// Deletes any existing test platform brightness and returns to using the
/// real platform brightness.
@Deprecated(
'Use platformDispatcher.clearPlatformBrightnessTestValue() instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
void clearPlatformBrightnessTestValue() {
_platformBrightnessTestValue = null;
onPlatformBrightnessChanged?.call();
platformDispatcher.clearPlatformBrightnessTestValue();
}
@override
bool get alwaysUse24HourFormat => _alwaysUse24HourFormatTestValue ?? platformDispatcher.alwaysUse24HourFormat;
bool? _alwaysUse24HourFormatTestValue;
bool get alwaysUse24HourFormat => platformDispatcher.alwaysUse24HourFormat;
/// Hides the real clock format and reports the given
/// [alwaysUse24HourFormatTestValue] instead.
@Deprecated(
'Use platformDispatcher.alwaysUse24HourFormatTestValue instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
set alwaysUse24HourFormatTestValue(bool alwaysUse24HourFormatTestValue) { // ignore: avoid_setters_without_getters
_alwaysUse24HourFormatTestValue = alwaysUse24HourFormatTestValue;
platformDispatcher.alwaysUse24HourFormatTestValue = alwaysUse24HourFormatTestValue;
}
/// Deletes any existing test clock format and returns to using the real clock
/// format.
@Deprecated(
'Use platformDispatcher.clearAlwaysUse24HourTestValue() instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
void clearAlwaysUse24HourTestValue() {
_alwaysUse24HourFormatTestValue = null;
platformDispatcher.clearAlwaysUse24HourTestValue();
}
@override
......@@ -272,12 +312,15 @@ class TestWindow implements ui.SingletonFlutterWindow {
}
@override
bool get brieflyShowPassword => _brieflyShowPasswordTestValue ?? platformDispatcher.brieflyShowPassword;
bool? _brieflyShowPasswordTestValue;
bool get brieflyShowPassword => platformDispatcher.brieflyShowPassword;
/// Hides the real [brieflyShowPassword] and reports the given
/// `brieflyShowPasswordTestValue` instead.
@Deprecated(
'Use platformDispatcher.brieflyShowPasswordTestValue instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
set brieflyShowPasswordTestValue(bool brieflyShowPasswordTestValue) { // ignore: avoid_setters_without_getters
_brieflyShowPasswordTestValue = brieflyShowPasswordTestValue;
platformDispatcher.brieflyShowPasswordTestValue = brieflyShowPasswordTestValue;
}
@override
......@@ -309,17 +352,24 @@ class TestWindow implements ui.SingletonFlutterWindow {
}
@override
String get defaultRouteName => _defaultRouteNameTestValue ?? platformDispatcher.defaultRouteName;
String? _defaultRouteNameTestValue;
String get defaultRouteName => platformDispatcher.defaultRouteName;
/// Hides the real default route name and reports the given
/// [defaultRouteNameTestValue] instead.
@Deprecated(
'Use platformDispatcher.defaultRouteNameTestValue instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
set defaultRouteNameTestValue(String defaultRouteNameTestValue) { // ignore: avoid_setters_without_getters
_defaultRouteNameTestValue = defaultRouteNameTestValue;
platformDispatcher.defaultRouteNameTestValue = defaultRouteNameTestValue;
}
/// Deletes any existing test default route name and returns to using the real
/// default route name.
@Deprecated(
'Use platformDispatcher.clearDefaultRouteNameTestValue instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
void clearDefaultRouteNameTestValue() {
_defaultRouteNameTestValue = null;
platformDispatcher.clearDefaultRouteNameTestValue();
}
@override
......@@ -333,19 +383,24 @@ class TestWindow implements ui.SingletonFlutterWindow {
}
@override
bool get semanticsEnabled => _semanticsEnabledTestValue ?? platformDispatcher.semanticsEnabled;
bool? _semanticsEnabledTestValue;
bool get semanticsEnabled => platformDispatcher.semanticsEnabled;
/// Hides the real semantics enabled and reports the given
/// [semanticsEnabledTestValue] instead.
@Deprecated(
'Use platformDispatcher.semanticsEnabledTestValue instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
set semanticsEnabledTestValue(bool semanticsEnabledTestValue) { // ignore: avoid_setters_without_getters
_semanticsEnabledTestValue = semanticsEnabledTestValue;
onSemanticsEnabledChanged?.call();
platformDispatcher.semanticsEnabledTestValue = semanticsEnabledTestValue;
}
/// Deletes any existing test semantics enabled and returns to using the real
/// semantics enabled.
@Deprecated(
'Use platformDispatcher.clearSemanticsEnabledTestValue instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
void clearSemanticsEnabledTestValue() {
_semanticsEnabledTestValue = null;
onSemanticsEnabledChanged?.call();
platformDispatcher.clearSemanticsEnabledTestValue();
}
@override
......@@ -363,22 +418,27 @@ class TestWindow implements ui.SingletonFlutterWindow {
}
@override
ui.AccessibilityFeatures get accessibilityFeatures => _accessibilityFeaturesTestValue ?? platformDispatcher.accessibilityFeatures;
ui.AccessibilityFeatures? _accessibilityFeaturesTestValue;
ui.AccessibilityFeatures get accessibilityFeatures => platformDispatcher.accessibilityFeatures;
/// Hides the real accessibility features and reports the given
/// [accessibilityFeaturesTestValue] instead.
///
/// Consider using [FakeAccessibilityFeatures] to provide specific
/// values for the various accessibility features under test.
@Deprecated(
'Use platformDispatcher.accessibilityFeaturesTestValue instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
set accessibilityFeaturesTestValue(ui.AccessibilityFeatures accessibilityFeaturesTestValue) { // ignore: avoid_setters_without_getters
_accessibilityFeaturesTestValue = accessibilityFeaturesTestValue;
onAccessibilityFeaturesChanged?.call();
platformDispatcher.accessibilityFeaturesTestValue = accessibilityFeaturesTestValue;
}
/// Deletes any existing test accessibility features and returns to using the
/// real accessibility features.
@Deprecated(
'Use platformDispatcher.clearAccessibilityFeaturesTestValue() instead. '
'This feature was deprecated after v2.11.0-0.0.pre.'
)
void clearAccessibilityFeaturesTestValue() {
_accessibilityFeaturesTestValue = null;
onAccessibilityFeaturesChanged?.call();
platformDispatcher.clearAccessibilityFeaturesTestValue();
}
@override
......@@ -432,29 +492,21 @@ class TestWindow implements ui.SingletonFlutterWindow {
platformDispatcher.onPlatformMessage = callback;
}
@override
ui.PlatformDispatcher get platformDispatcher => _window.platformDispatcher;
/// Delete any test value properties that have been set on this [TestWindow]
/// and return to reporting the real [SingletonFlutterWindow] values for all
/// [SingletonFlutterWindow] properties.
/// as well as its [platformDispatcher].
///
/// After calling this, the real [SingletonFlutterWindow] and
/// [ui.PlatformDispatcher] values are reported again.
///
/// If desired, clearing of properties can be done on an individual basis,
/// e.g., [clearLocaleTestValue()].
void clearAllTestValues() {
clearAccessibilityFeaturesTestValue();
clearAlwaysUse24HourTestValue();
clearDefaultRouteNameTestValue();
clearDevicePixelRatioTestValue();
clearPlatformBrightnessTestValue();
clearLocaleTestValue();
clearLocalesTestValue();
clearPaddingTestValue();
clearDisplayFeaturesTestValue();
clearPhysicalSizeTestValue();
clearSemanticsEnabledTestValue();
clearTextScaleFactorTestValue();
clearViewInsetsTestValue();
platformDispatcher.clearAllTestValues();
}
/// This gives us some grace time when the dart:ui side adds something to
......@@ -542,3 +594,339 @@ class FakeAccessibilityFeatures implements ui.AccessibilityFeatures {
return null;
}
}
/// [PlatformDispatcher] that wraps another [PlatformDispatcher] and
/// allows faking of some properties for testing purposes.
///
/// See also:
///
/// * [TestWindow], which wraps a [SingletonFlutterWindow] for
/// testing and mocking purposes.
class TestPlatformDispatcher implements ui.PlatformDispatcher {
/// Constructs a [TestPlatformDispatcher] that defers all behavior to the given
/// [dart:ui.PlatformDispatcher] unless explicitly overridden for test purposes.
TestPlatformDispatcher({
required ui.PlatformDispatcher platformDispatcher,
}) : _platformDispatcher = platformDispatcher;
/// The [dart:ui.PlatformDispatcher] that is wrapped by this [TestPlatformDispatcher].
final ui.PlatformDispatcher _platformDispatcher;
@override
ui.VoidCallback? get onMetricsChanged => _platformDispatcher.onMetricsChanged;
@override
set onMetricsChanged(ui.VoidCallback? callback) {
_platformDispatcher.onMetricsChanged = callback;
}
@override
ui.Locale get locale => _localeTestValue ?? _platformDispatcher.locale;
ui.Locale? _localeTestValue;
/// Hides the real locale and reports the given [localeTestValue] instead.
set localeTestValue(ui.Locale localeTestValue) { // ignore: avoid_setters_without_getters
_localeTestValue = localeTestValue;
onLocaleChanged?.call();
}
/// Deletes any existing test locale and returns to using the real locale.
void clearLocaleTestValue() {
_localeTestValue = null;
onLocaleChanged?.call();
}
@override
List<ui.Locale> get locales => _localesTestValue ?? _platformDispatcher.locales;
List<ui.Locale>? _localesTestValue;
/// Hides the real locales and reports the given [localesTestValue] instead.
set localesTestValue(List<ui.Locale> localesTestValue) { // ignore: avoid_setters_without_getters
_localesTestValue = localesTestValue;
onLocaleChanged?.call();
}
/// Deletes any existing test locales and returns to using the real locales.
void clearLocalesTestValue() {
_localesTestValue = null;
onLocaleChanged?.call();
}
@override
ui.VoidCallback? get onLocaleChanged => _platformDispatcher.onLocaleChanged;
@override
set onLocaleChanged(ui.VoidCallback? callback) {
_platformDispatcher.onLocaleChanged = callback;
}
@override
String get initialLifecycleState => _initialLifecycleStateTestValue;
String _initialLifecycleStateTestValue = '';
/// Sets a faked initialLifecycleState for testing.
set initialLifecycleStateTestValue(String state) { // ignore: avoid_setters_without_getters
_initialLifecycleStateTestValue = state;
}
@override
double get textScaleFactor => _textScaleFactorTestValue ?? _platformDispatcher.textScaleFactor;
double? _textScaleFactorTestValue;
/// Hides the real text scale factor and reports the given
/// [textScaleFactorTestValue] instead.
set textScaleFactorTestValue(double textScaleFactorTestValue) { // ignore: avoid_setters_without_getters
_textScaleFactorTestValue = textScaleFactorTestValue;
onTextScaleFactorChanged?.call();
}
/// Deletes any existing test text scale factor and returns to using the real
/// text scale factor.
void clearTextScaleFactorTestValue() {
_textScaleFactorTestValue = null;
onTextScaleFactorChanged?.call();
}
@override
ui.Brightness get platformBrightness => _platformBrightnessTestValue ?? _platformDispatcher.platformBrightness;
ui.Brightness? _platformBrightnessTestValue;
@override
ui.VoidCallback? get onPlatformBrightnessChanged => _platformDispatcher.onPlatformBrightnessChanged;
@override
set onPlatformBrightnessChanged(ui.VoidCallback? callback) {
_platformDispatcher.onPlatformBrightnessChanged = callback;
}
/// Hides the real text scale factor and reports the given
/// [platformBrightnessTestValue] instead.
set platformBrightnessTestValue(ui.Brightness platformBrightnessTestValue) { // ignore: avoid_setters_without_getters
_platformBrightnessTestValue = platformBrightnessTestValue;
onPlatformBrightnessChanged?.call();
}
/// Deletes any existing test platform brightness and returns to using the
/// real platform brightness.
void clearPlatformBrightnessTestValue() {
_platformBrightnessTestValue = null;
onPlatformBrightnessChanged?.call();
}
@override
bool get alwaysUse24HourFormat => _alwaysUse24HourFormatTestValue ?? _platformDispatcher.alwaysUse24HourFormat;
bool? _alwaysUse24HourFormatTestValue;
/// Hides the real clock format and reports the given
/// [alwaysUse24HourFormatTestValue] instead.
set alwaysUse24HourFormatTestValue(bool alwaysUse24HourFormatTestValue) { // ignore: avoid_setters_without_getters
_alwaysUse24HourFormatTestValue = alwaysUse24HourFormatTestValue;
}
/// Deletes any existing test clock format and returns to using the real clock
/// format.
void clearAlwaysUse24HourTestValue() {
_alwaysUse24HourFormatTestValue = null;
}
@override
ui.VoidCallback? get onTextScaleFactorChanged => _platformDispatcher.onTextScaleFactorChanged;
@override
set onTextScaleFactorChanged(ui.VoidCallback? callback) {
_platformDispatcher.onTextScaleFactorChanged = callback;
}
@override
bool get brieflyShowPassword => _brieflyShowPasswordTestValue ?? _platformDispatcher.brieflyShowPassword;
bool? _brieflyShowPasswordTestValue;
/// Hides the real [brieflyShowPassword] and reports the given
/// `brieflyShowPasswordTestValue` instead.
set brieflyShowPasswordTestValue(bool brieflyShowPasswordTestValue) { // ignore: avoid_setters_without_getters
_brieflyShowPasswordTestValue = brieflyShowPasswordTestValue;
}
@override
ui.FrameCallback? get onBeginFrame => _platformDispatcher.onBeginFrame;
@override
set onBeginFrame(ui.FrameCallback? callback) {
_platformDispatcher.onBeginFrame = callback;
}
@override
ui.VoidCallback? get onDrawFrame => _platformDispatcher.onDrawFrame;
@override
set onDrawFrame(ui.VoidCallback? callback) {
_platformDispatcher.onDrawFrame = callback;
}
@override
ui.TimingsCallback? get onReportTimings => _platformDispatcher.onReportTimings;
@override
set onReportTimings(ui.TimingsCallback? callback) {
_platformDispatcher.onReportTimings = callback;
}
@override
ui.PointerDataPacketCallback? get onPointerDataPacket => _platformDispatcher.onPointerDataPacket;
@override
set onPointerDataPacket(ui.PointerDataPacketCallback? callback) {
_platformDispatcher.onPointerDataPacket = callback;
}
@override
String get defaultRouteName => _defaultRouteNameTestValue ?? _platformDispatcher.defaultRouteName;
String? _defaultRouteNameTestValue;
/// Hides the real default route name and reports the given
/// [defaultRouteNameTestValue] instead.
set defaultRouteNameTestValue(String defaultRouteNameTestValue) { // ignore: avoid_setters_without_getters
_defaultRouteNameTestValue = defaultRouteNameTestValue;
}
/// Deletes any existing test default route name and returns to using the real
/// default route name.
void clearDefaultRouteNameTestValue() {
_defaultRouteNameTestValue = null;
}
@override
void scheduleFrame() {
_platformDispatcher.scheduleFrame();
}
@override
bool get semanticsEnabled => _semanticsEnabledTestValue ?? _platformDispatcher.semanticsEnabled;
bool? _semanticsEnabledTestValue;
/// Hides the real semantics enabled and reports the given
/// [semanticsEnabledTestValue] instead.
set semanticsEnabledTestValue(bool semanticsEnabledTestValue) { // ignore: avoid_setters_without_getters
_semanticsEnabledTestValue = semanticsEnabledTestValue;
onSemanticsEnabledChanged?.call();
}
/// Deletes any existing test semantics enabled and returns to using the real
/// semantics enabled.
void clearSemanticsEnabledTestValue() {
_semanticsEnabledTestValue = null;
onSemanticsEnabledChanged?.call();
}
@override
ui.VoidCallback? get onSemanticsEnabledChanged => _platformDispatcher.onSemanticsEnabledChanged;
@override
set onSemanticsEnabledChanged(ui.VoidCallback? callback) {
_platformDispatcher.onSemanticsEnabledChanged = callback;
}
@override
ui.SemanticsActionCallback? get onSemanticsAction => _platformDispatcher.onSemanticsAction;
@override
set onSemanticsAction(ui.SemanticsActionCallback? callback) {
_platformDispatcher.onSemanticsAction = callback;
}
@override
ui.AccessibilityFeatures get accessibilityFeatures => _accessibilityFeaturesTestValue ?? _platformDispatcher.accessibilityFeatures;
ui.AccessibilityFeatures? _accessibilityFeaturesTestValue;
/// Hides the real accessibility features and reports the given
/// [accessibilityFeaturesTestValue] instead.
///
/// Consider using [FakeAccessibilityFeatures] to provide specific
/// values for the various accessibility features under test.
set accessibilityFeaturesTestValue(ui.AccessibilityFeatures accessibilityFeaturesTestValue) { // ignore: avoid_setters_without_getters
_accessibilityFeaturesTestValue = accessibilityFeaturesTestValue;
onAccessibilityFeaturesChanged?.call();
}
/// Deletes any existing test accessibility features and returns to using the
/// real accessibility features.
void clearAccessibilityFeaturesTestValue() {
_accessibilityFeaturesTestValue = null;
onAccessibilityFeaturesChanged?.call();
}
@override
ui.VoidCallback? get onAccessibilityFeaturesChanged => _platformDispatcher.onAccessibilityFeaturesChanged;
@override
set onAccessibilityFeaturesChanged(ui.VoidCallback? callback) {
_platformDispatcher.onAccessibilityFeaturesChanged = callback;
}
@override
void updateSemantics(ui.SemanticsUpdate update) {
_platformDispatcher.updateSemantics(update);
}
@override
void setIsolateDebugName(String name) {
_platformDispatcher.setIsolateDebugName(name);
}
@override
void sendPlatformMessage(
String name,
ByteData? data,
ui.PlatformMessageResponseCallback? callback,
) {
_platformDispatcher.sendPlatformMessage(name, data, callback);
}
@Deprecated(
'Instead of calling this callback, use ServicesBinding.instance.channelBuffers.push. '
'This feature was deprecated after v2.1.0-10.0.pre.'
)
@override
ui.PlatformMessageCallback? get onPlatformMessage => _platformDispatcher.onPlatformMessage;
@Deprecated(
'Instead of setting this callback, use ServicesBinding.instance.defaultBinaryMessenger.setMessageHandler. '
'This feature was deprecated after v2.1.0-10.0.pre.'
)
@override
set onPlatformMessage(ui.PlatformMessageCallback? callback) {
_platformDispatcher.onPlatformMessage = callback;
}
/// Delete any test value properties that have been set on this [TestPlatformDispatcher]
/// and return to reporting the real [ui.PlatformDispatcher] values for all
/// [PlatformDispatcher] properties.
///
/// If desired, clearing of properties can be done on an individual basis,
/// e.g., [clearLocaleTestValue()].
void clearAllTestValues() {
clearAccessibilityFeaturesTestValue();
clearAlwaysUse24HourTestValue();
clearDefaultRouteNameTestValue();
clearPlatformBrightnessTestValue();
clearLocaleTestValue();
clearLocalesTestValue();
clearSemanticsEnabledTestValue();
clearTextScaleFactorTestValue();
}
@override
ui.VoidCallback? get onFrameDataChanged => _platformDispatcher.onFrameDataChanged;
@override
set onFrameDataChanged(ui.VoidCallback? value) {
_platformDispatcher.onFrameDataChanged = value;
}
@override
ui.KeyDataCallback? get onKeyData => _platformDispatcher.onKeyData;
@override
set onKeyData(ui.KeyDataCallback? onKeyData) {
_platformDispatcher.onKeyData = onKeyData;
}
@override
ui.VoidCallback? get onPlatformConfigurationChanged => _platformDispatcher.onPlatformConfigurationChanged;
@override
set onPlatformConfigurationChanged(ui.VoidCallback? onPlatformConfigurationChanged) {
_platformDispatcher.onPlatformConfigurationChanged = onPlatformConfigurationChanged;
}
@override
ui.Locale? computePlatformResolvedLocale(List<ui.Locale> supportedLocales) => _platformDispatcher.computePlatformResolvedLocale(supportedLocales);
@override
ui.PlatformConfiguration get configuration => _platformDispatcher.configuration;
@override
ui.FrameData get frameData => _platformDispatcher.frameData;
@override
ByteData? getPersistentIsolateData() => _platformDispatcher.getPersistentIsolateData();
@override
Iterable<ui.FlutterView> get views => _platformDispatcher.views;
/// This gives us some grace time when the dart:ui side adds something to
/// [PlatformDispatcher], and makes things easier when we do rolls to give
/// us time to catch up.
@override
dynamic noSuchMethod(Invocation invocation) {
return null;
}
}
// 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 'dart:ui' show Locale, AccessibilityFeatures, Brightness, PlatformDispatcher;
import 'package:flutter/widgets.dart' show WidgetsBinding, WidgetsBindingObserver;
import 'package:flutter_test/flutter_test.dart';
void main() {
test('TestWindow can handle new methods without breaking', () {
final dynamic testPlatformDispatcher = TestPlatformDispatcher(platformDispatcher: PlatformDispatcher.instance);
// ignore: avoid_dynamic_calls
expect(testPlatformDispatcher.someNewProperty, null);
});
testWidgets('TestWindow can fake locale', (WidgetTester tester) async {
verifyThatTestPlatformDispatcherCanFakeProperty<Locale>(
tester: tester,
realValue: PlatformDispatcher.instance.locale,
fakeValue: const Locale('fake_language_code'),
propertyRetriever: () {
return WidgetsBinding.instance.platformDispatcher.locale;
},
propertyFaker: (TestWidgetsFlutterBinding binding, Locale fakeValue) {
binding.platformDispatcher.localeTestValue = fakeValue;
},
);
});
testWidgets('TestWindow can fake locales', (WidgetTester tester) async {
verifyThatTestPlatformDispatcherCanFakeProperty<List<Locale>>(
tester: tester,
realValue: PlatformDispatcher.instance.locales,
fakeValue: <Locale>[const Locale('fake_language_code')],
propertyRetriever: () {
return WidgetsBinding.instance.platformDispatcher.locales;
},
propertyFaker: (TestWidgetsFlutterBinding binding, List<Locale> fakeValue) {
binding.platformDispatcher.localesTestValue = fakeValue;
},
);
});
testWidgets('TestWindow can fake text scale factor', (WidgetTester tester) async {
verifyThatTestPlatformDispatcherCanFakeProperty<double>(
tester: tester,
realValue: PlatformDispatcher.instance.textScaleFactor,
fakeValue: 2.5,
propertyRetriever: () {
return WidgetsBinding.instance.platformDispatcher.textScaleFactor;
},
propertyFaker: (TestWidgetsFlutterBinding binding, double fakeValue) {
binding.platformDispatcher.textScaleFactorTestValue = fakeValue;
},
);
});
testWidgets('TestWindow can fake clock format', (WidgetTester tester) async {
verifyThatTestPlatformDispatcherCanFakeProperty<bool>(
tester: tester,
realValue: PlatformDispatcher.instance.alwaysUse24HourFormat,
fakeValue: !PlatformDispatcher.instance.alwaysUse24HourFormat,
propertyRetriever: () {
return WidgetsBinding.instance.platformDispatcher.alwaysUse24HourFormat;
},
propertyFaker: (TestWidgetsFlutterBinding binding, bool fakeValue) {
binding.platformDispatcher.alwaysUse24HourFormatTestValue = fakeValue;
},
);
});
testWidgets('TestWindow can fake brieflyShowPassword', (WidgetTester tester) async {
verifyThatTestPlatformDispatcherCanFakeProperty<bool>(
tester: tester,
realValue: PlatformDispatcher.instance.brieflyShowPassword,
fakeValue: !PlatformDispatcher.instance.brieflyShowPassword,
propertyRetriever: () => WidgetsBinding.instance.platformDispatcher.brieflyShowPassword,
propertyFaker: (TestWidgetsFlutterBinding binding, bool fakeValue) {
binding.platformDispatcher.brieflyShowPasswordTestValue = fakeValue;
},
);
});
testWidgets('TestWindow can fake default route name', (WidgetTester tester) async {
verifyThatTestPlatformDispatcherCanFakeProperty<String>(
tester: tester,
realValue: PlatformDispatcher.instance.defaultRouteName,
fakeValue: 'fake_route',
propertyRetriever: () {
return WidgetsBinding.instance.platformDispatcher.defaultRouteName;
},
propertyFaker: (TestWidgetsFlutterBinding binding, String fakeValue) {
binding.platformDispatcher.defaultRouteNameTestValue = fakeValue;
},
);
});
testWidgets('TestWindow can fake accessibility features', (WidgetTester tester) async {
verifyThatTestPlatformDispatcherCanFakeProperty<AccessibilityFeatures>(
tester: tester,
realValue: PlatformDispatcher.instance.accessibilityFeatures,
fakeValue: const FakeAccessibilityFeatures(),
propertyRetriever: () {
return WidgetsBinding.instance.platformDispatcher.accessibilityFeatures;
},
propertyFaker: (TestWidgetsFlutterBinding binding, AccessibilityFeatures fakeValue) {
binding.platformDispatcher.accessibilityFeaturesTestValue = fakeValue;
},
);
});
testWidgets('TestWindow can fake platform brightness', (WidgetTester tester) async {
verifyThatTestPlatformDispatcherCanFakeProperty<Brightness>(
tester: tester,
realValue: Brightness.light,
fakeValue: Brightness.dark,
propertyRetriever: () {
return WidgetsBinding.instance.platformDispatcher.platformBrightness;
},
propertyFaker: (TestWidgetsFlutterBinding binding, Brightness fakeValue) {
binding.platformDispatcher.platformBrightnessTestValue = fakeValue;
},
);
});
testWidgets('TestWindow can clear out fake properties all at once', (WidgetTester tester) async {
final Locale originalLocale = PlatformDispatcher.instance.locale;
final double originalTextScaleFactor = PlatformDispatcher.instance.textScaleFactor;
final TestPlatformDispatcher testPlatformDispatcher = retrieveTestBinding(tester).platformDispatcher;
// Set fake values for window properties.
testPlatformDispatcher.localeTestValue = const Locale('foobar');
testPlatformDispatcher.textScaleFactorTestValue = 3.0;
// Erase fake window property values.
testPlatformDispatcher.clearAllTestValues();
// Verify that the window once again reports real property values.
expect(WidgetsBinding.instance.platformDispatcher.locale, originalLocale);
expect(WidgetsBinding.instance.platformDispatcher.textScaleFactor, originalTextScaleFactor);
});
testWidgets('TestWindow sends fake locales when WidgetsBindingObserver notifiers are called', (WidgetTester tester) async {
final List<Locale> defaultLocales = WidgetsBinding.instance.platformDispatcher.locales;
final TestObserver observer = TestObserver();
retrieveTestBinding(tester).addObserver(observer);
final List<Locale> expectedValue = <Locale>[const Locale('fake_language_code')];
retrieveTestBinding(tester).platformDispatcher.localesTestValue = expectedValue;
expect(observer.locales, equals(expectedValue));
retrieveTestBinding(tester).platformDispatcher.localesTestValue = defaultLocales;
});
}
void verifyThatTestPlatformDispatcherCanFakeProperty<PlatformDispatcherPropertyType>({
required WidgetTester tester,
required PlatformDispatcherPropertyType? realValue,
required PlatformDispatcherPropertyType fakeValue,
required PlatformDispatcherPropertyType? Function() propertyRetriever,
required Function(TestWidgetsFlutterBinding, PlatformDispatcherPropertyType fakeValue) propertyFaker,
}) {
PlatformDispatcherPropertyType? propertyBeforeFaking;
PlatformDispatcherPropertyType? propertyAfterFaking;
propertyBeforeFaking = propertyRetriever();
propertyFaker(retrieveTestBinding(tester), fakeValue);
propertyAfterFaking = propertyRetriever();
expect(propertyBeforeFaking, realValue);
expect(propertyAfterFaking, fakeValue);
}
TestWidgetsFlutterBinding retrieveTestBinding(WidgetTester tester) {
final WidgetsBinding binding = tester.binding;
assert(binding is TestWidgetsFlutterBinding);
final TestWidgetsFlutterBinding testBinding = binding as TestWidgetsFlutterBinding;
return testBinding;
}
class TestObserver with WidgetsBindingObserver {
List<Locale>? locales;
Locale? locale;
@override
void didChangeLocales(List<Locale>? locales) {
this.locales = locales;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment