// 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.

/// @docImport 'package:flutter/material.dart';
///
/// @docImport 'binding.dart';
/// @docImport 'widget_tester.dart';
library;

import 'dart:ui' hide window;

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';

/// Test version of [AccessibilityFeatures] in which specific features may
/// be set to arbitrary values.
///
/// By default, all features are disabled. For an instance where all the
/// features are enabled, consider the [FakeAccessibilityFeatures.allOn]
/// constant.
@immutable
class FakeAccessibilityFeatures implements AccessibilityFeatures {
  /// Creates a test instance of [AccessibilityFeatures].
  ///
  /// By default, all features are disabled.
  const FakeAccessibilityFeatures({
    this.accessibleNavigation = false,
    this.invertColors = false,
    this.disableAnimations = false,
    this.boldText = false,
    this.reduceMotion = false,
    this.highContrast = false,
    this.onOffSwitchLabels = false,
    this.supportsAnnounce = false,
    this.autoPlayAnimatedImages = false,
    this.autoPlayVideos = false,
    this.deterministicCursor = false,
  });

  /// An instance of [AccessibilityFeatures] where all the features are enabled.
  static const FakeAccessibilityFeatures allOn = FakeAccessibilityFeatures(
    accessibleNavigation: true,
    invertColors: true,
    disableAnimations: true,
    boldText: true,
    reduceMotion: true,
    highContrast: true,
    onOffSwitchLabels: true,
    supportsAnnounce: true,
    autoPlayAnimatedImages: true,
    autoPlayVideos: true,
    deterministicCursor: true,
  );

  @override
  final bool accessibleNavigation;

  @override
  final bool invertColors;

  @override
  final bool disableAnimations;

  @override
  final bool boldText;

  @override
  final bool reduceMotion;

  @override
  final bool highContrast;

  @override
  final bool onOffSwitchLabels;

  @override
  final bool supportsAnnounce;

  @override
  final bool autoPlayAnimatedImages;

  @override
  final bool autoPlayVideos;

  @override
  final bool deterministicCursor;

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is FakeAccessibilityFeatures &&
        other.accessibleNavigation == accessibleNavigation &&
        other.invertColors == invertColors &&
        other.disableAnimations == disableAnimations &&
        other.boldText == boldText &&
        other.reduceMotion == reduceMotion &&
        other.highContrast == highContrast &&
        other.onOffSwitchLabels == onOffSwitchLabels &&
        other.supportsAnnounce == supportsAnnounce &&
        other.autoPlayAnimatedImages == autoPlayAnimatedImages &&
        other.autoPlayVideos == autoPlayVideos &&
        other.deterministicCursor == deterministicCursor;
  }

  @override
  int get hashCode {
    return Object.hash(
      accessibleNavigation,
      invertColors,
      disableAnimations,
      boldText,
      reduceMotion,
      highContrast,
      onOffSwitchLabels,
      supportsAnnounce,
      autoPlayAnimatedImages,
      autoPlayVideos,
      deterministicCursor,
    );
  }

  /// This gives us some grace time when the dart:ui side adds something to
  /// [AccessibilityFeatures], and makes things easier when we do rolls to
  /// give us time to catch up.
  ///
  /// If you would like to add to this class, changes must first be made in the
  /// engine, followed by the framework.
  @override
  dynamic noSuchMethod(Invocation invocation) {
    return null;
  }
}

/// Used to fake insets and padding for [TestFlutterView]s.
///
/// See also:
///
///   * [TestFlutterView.padding], [TestFlutterView.systemGestureInsets],
///     [TestFlutterView.viewInsets], and [TestFlutterView.viewPadding] for test
///     properties that make use of [FakeViewPadding].
@immutable
class FakeViewPadding implements ViewPadding {
  /// Instantiates a new [FakeViewPadding] object for faking insets and padding
  /// during tests.
  const FakeViewPadding({this.left = 0.0, this.top = 0.0, this.right = 0.0, this.bottom = 0.0});

  FakeViewPadding._wrap(ViewPadding base)
    : left = base.left,
      top = base.top,
      right = base.right,
      bottom = base.bottom;

  /// A view padding that has zeros for each edge.
  static const FakeViewPadding zero = FakeViewPadding();

  @override
  final double left;

  @override
  final double top;

  @override
  final double right;

  @override
  final double bottom;
}

/// [PlatformDispatcher] that wraps another [PlatformDispatcher] and
/// allows faking of some properties for testing purposes.
///
/// See also:
///
///   * [TestFlutterView], which wraps a [FlutterView] for testing and
///     mocking purposes.
class TestPlatformDispatcher implements PlatformDispatcher {
  /// Constructs a [TestPlatformDispatcher] that defers all behavior to the given
  /// [PlatformDispatcher] unless explicitly overridden for test purposes.
  TestPlatformDispatcher({required PlatformDispatcher platformDispatcher})
    : _platformDispatcher = platformDispatcher {
    _updateViewsAndDisplays();
    _platformDispatcher.onMetricsChanged = _handleMetricsChanged;
    _platformDispatcher.onViewFocusChange = _handleViewFocusChanged;
  }

  /// The [PlatformDispatcher] that is wrapped by this [TestPlatformDispatcher].
  final PlatformDispatcher _platformDispatcher;

  @override
  TestFlutterView? get implicitView {
    return _platformDispatcher.implicitView != null
        ? _testViews[_platformDispatcher.implicitView!.viewId]!
        : null;
  }

  @override
  int? get engineId => 1;

  final Map<int, TestFlutterView> _testViews = <int, TestFlutterView>{};
  final Map<int, TestDisplay> _testDisplays = <int, TestDisplay>{};

  @override
  VoidCallback? get onMetricsChanged => _platformDispatcher.onMetricsChanged;
  VoidCallback? _onMetricsChanged;
  @override
  set onMetricsChanged(VoidCallback? callback) {
    _onMetricsChanged = callback;
  }

  void _handleMetricsChanged() {
    _updateViewsAndDisplays();
    _onMetricsChanged?.call();
  }

  @override
  ViewFocusChangeCallback? get onViewFocusChange => _platformDispatcher.onViewFocusChange;
  ViewFocusChangeCallback? _onViewFocusChange;
  @override
  set onViewFocusChange(ViewFocusChangeCallback? callback) {
    _onViewFocusChange = callback;
  }

  void _handleViewFocusChanged(ViewFocusEvent event) {
    _updateViewsAndDisplays();
    _currentlyFocusedViewId = switch (event.state) {
      ViewFocusState.focused => event.viewId,
      ViewFocusState.unfocused => null,
    };
    _onViewFocusChange?.call(event);
  }

  /// Returns the list of [ViewFocusEvent]s that have been received by
  /// [requestViewFocusChange] since the last call to
  /// [resetFocusedViewTestValues].
  ///
  /// Clearing or modifying the returned list will do nothing (it's a copy).
  /// Call [resetFocusedViewTestValues] to clear.
  List<ViewFocusEvent> get testFocusEvents => _testFocusEvents.toList();
  final List<ViewFocusEvent> _testFocusEvents = <ViewFocusEvent>[];

  /// Returns the last view ID to be focused by [onViewFocusChange].
  /// Returns null if no views are focused.
  ///
  /// Can be reset to null with [resetFocusedViewTestValues].
  int? get currentlyFocusedViewIdTestValue => _currentlyFocusedViewId;
  int? _currentlyFocusedViewId;

  /// Clears [testFocusEvents] and sets [currentlyFocusedViewIdTestValue] to
  /// null.
  void resetFocusedViewTestValues() {
    if (_currentlyFocusedViewId != null) {
      // If there is a focused view, then tell everyone who still cares that
      // it's unfocusing.
      _platformDispatcher.onViewFocusChange?.call(
        ViewFocusEvent(
          viewId: _currentlyFocusedViewId!,
          state: ViewFocusState.unfocused,
          direction: ViewFocusDirection.undefined,
        ),
      );
      _currentlyFocusedViewId = null;
    }
    _testFocusEvents.clear();
  }

  @override
  void requestViewFocusChange({
    required int viewId,
    required ViewFocusState state,
    required ViewFocusDirection direction,
  }) {
    _testFocusEvents.add(ViewFocusEvent(viewId: viewId, state: state, direction: direction));
    _platformDispatcher.requestViewFocusChange(viewId: viewId, state: state, direction: direction);
  }

  @override
  Locale get locale => _localeTestValue ?? _platformDispatcher.locale;
  Locale? _localeTestValue;

  /// Hides the real locale and reports the given [localeTestValue] instead.
  // ignore: avoid_setters_without_getters
  set localeTestValue(Locale localeTestValue) {
    _localeTestValue = localeTestValue;
    onLocaleChanged?.call();
  }

  /// Deletes any existing test locale and returns to using the real locale.
  void clearLocaleTestValue() {
    _localeTestValue = null;
    onLocaleChanged?.call();
  }

  @override
  List<Locale> get locales => _localesTestValue ?? _platformDispatcher.locales;
  List<Locale>? _localesTestValue;

  /// Hides the real locales and reports the given [localesTestValue] instead.
  // ignore: avoid_setters_without_getters
  set localesTestValue(List<Locale> localesTestValue) {
    _localesTestValue = localesTestValue;
    onLocaleChanged?.call();
  }

  /// Deletes any existing test locales and returns to using the real locales.
  void clearLocalesTestValue() {
    _localesTestValue = null;
    onLocaleChanged?.call();
  }

  @override
  VoidCallback? get onLocaleChanged => _platformDispatcher.onLocaleChanged;
  @override
  set onLocaleChanged(VoidCallback? callback) {
    _platformDispatcher.onLocaleChanged = callback;
  }

  @override
  String get initialLifecycleState => _initialLifecycleStateTestValue;
  String _initialLifecycleStateTestValue = '';

  /// Sets a faked initialLifecycleState for testing.
  // ignore: avoid_setters_without_getters
  set initialLifecycleStateTestValue(String state) {
    _initialLifecycleStateTestValue = state;
  }

  /// Resets [initialLifecycleState] to the default value for the platform.
  void resetInitialLifecycleState() {
    _initialLifecycleStateTestValue = '';
  }

  @override
  double get textScaleFactor => _textScaleFactorTestValue ?? _platformDispatcher.textScaleFactor;
  double? _textScaleFactorTestValue;

  /// Hides the real text scale factor and reports the given
  /// [textScaleFactorTestValue] instead.
  // ignore: avoid_setters_without_getters
  set textScaleFactorTestValue(double textScaleFactorTestValue) {
    _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
  double scaleFontSize(double unscaledFontSize) => textScaleFactor * unscaledFontSize;

  @override
  Brightness get platformBrightness =>
      _platformBrightnessTestValue ?? _platformDispatcher.platformBrightness;
  Brightness? _platformBrightnessTestValue;
  @override
  VoidCallback? get onPlatformBrightnessChanged => _platformDispatcher.onPlatformBrightnessChanged;
  @override
  set onPlatformBrightnessChanged(VoidCallback? callback) {
    _platformDispatcher.onPlatformBrightnessChanged = callback;
  }

  /// Hides the real platform brightness and reports the given
  /// [platformBrightnessTestValue] instead.
  // ignore: avoid_setters_without_getters
  set platformBrightnessTestValue(Brightness platformBrightnessTestValue) {
    _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.
  // ignore: avoid_setters_without_getters
  set alwaysUse24HourFormatTestValue(bool alwaysUse24HourFormatTestValue) {
    _alwaysUse24HourFormatTestValue = alwaysUse24HourFormatTestValue;
  }

  /// Deletes any existing test clock format and returns to using the real clock
  /// format.
  void clearAlwaysUse24HourTestValue() {
    _alwaysUse24HourFormatTestValue = null;
  }

  @override
  VoidCallback? get onTextScaleFactorChanged => _platformDispatcher.onTextScaleFactorChanged;
  @override
  set onTextScaleFactorChanged(VoidCallback? callback) {
    _platformDispatcher.onTextScaleFactorChanged = callback;
  }

  @override
  bool get nativeSpellCheckServiceDefined =>
      _nativeSpellCheckServiceDefinedTestValue ??
      _platformDispatcher.nativeSpellCheckServiceDefined;
  bool? _nativeSpellCheckServiceDefinedTestValue;
  // ignore: avoid_setters_without_getters
  set nativeSpellCheckServiceDefinedTestValue(bool nativeSpellCheckServiceDefinedTestValue) {
    _nativeSpellCheckServiceDefinedTestValue = nativeSpellCheckServiceDefinedTestValue;
  }

  /// Deletes existing value that determines whether or not a native spell check
  /// service is defined and returns to the real value.
  void clearNativeSpellCheckServiceDefined() {
    _nativeSpellCheckServiceDefinedTestValue = null;
  }

  @override
  bool get supportsShowingSystemContextMenu =>
      _supportsShowingSystemContextMenu ?? _platformDispatcher.supportsShowingSystemContextMenu;
  bool? _supportsShowingSystemContextMenu;
  set supportsShowingSystemContextMenu(bool value) {
    _supportsShowingSystemContextMenu = value;
  }

  /// Resets [supportsShowingSystemContextMenu] to the default value.
  void resetSupportsShowingSystemContextMenu() {
    _supportsShowingSystemContextMenu = null;
  }

  @override
  bool get brieflyShowPassword =>
      _brieflyShowPasswordTestValue ?? _platformDispatcher.brieflyShowPassword;
  bool? _brieflyShowPasswordTestValue;

  /// Hides the real [brieflyShowPassword] and reports the given
  /// `brieflyShowPasswordTestValue` instead.
  // ignore: avoid_setters_without_getters
  set brieflyShowPasswordTestValue(bool brieflyShowPasswordTestValue) {
    _brieflyShowPasswordTestValue = brieflyShowPasswordTestValue;
  }

  /// Resets [brieflyShowPassword] to the default value for the platform.
  void resetBrieflyShowPassword() {
    _brieflyShowPasswordTestValue = null;
  }

  /// The system-suggested height of the text, as a multiple of the font size.
  ///
  /// This value takes precedence over any text height specified at the
  /// application level. For example, at framework level, in the [TextStyle]
  /// for [Text], [SelectableText], and [EditableText] widgets, this value
  /// overrides the existing value of [TextStyle.height] and [StrutStyle.height].
  ///
  /// Returns null when no override has been set by the system.
  ///
  /// Defaults to the value provided by [PlatformDispatcher.lineHeightScaleFactorOverride].
  /// This can only be set in a test environment to emulate different platform
  /// configurations. A standard [PlatformDispatcher] is not mutable from the
  /// framework.
  ///
  /// Setting this value to `null` will force [lineHeightScaleFactorOverride] to return
  /// `null`. If you want to have the value default to the platform
  /// [lineHeightScaleFactorOverride], use [clearLineHeightScaleFactorOverrideTestValue].
  ///
  /// See also:
  ///
  ///   * [PlatformDispatcher.lineHeightScaleFactorOverride] for the standard implementation
  ///   * [clearLineHeightScaleFactorOverrideTestValue] to reset this value specifically
  ///   * [clearAllTestValues] to reset all test values for this view
  @override
  double? get lineHeightScaleFactorOverride => _forceLineHeightScaleFactorOverrideToBeNull
      ? null
      : _lineHeightScaleFactorOverrideTestValue ??
            _platformDispatcher.lineHeightScaleFactorOverride;
  double? _lineHeightScaleFactorOverrideTestValue;
  bool _forceLineHeightScaleFactorOverrideToBeNull = false;

  /// Hides the real line height scale factor and reports the given
  /// [lineHeightScaleFactorOverrideTestValue] instead.
  // ignore: avoid_setters_without_getters
  set lineHeightScaleFactorOverrideTestValue(double? lineHeightScaleFactorOverrideTestValue) {
    _lineHeightScaleFactorOverrideTestValue = lineHeightScaleFactorOverrideTestValue;
    if (lineHeightScaleFactorOverrideTestValue == null) {
      _forceLineHeightScaleFactorOverrideToBeNull = true;
    }
    onMetricsChanged?.call();
  }

  /// Deletes any existing test line height scale factor and returns to using
  /// the real line height scale factor.
  void clearLineHeightScaleFactorOverrideTestValue() {
    _lineHeightScaleFactorOverrideTestValue = null;
    _forceLineHeightScaleFactorOverrideToBeNull = false;
    onMetricsChanged?.call();
  }

  /// The system-suggested amount of additional space (in logical pixels)
  /// to add between each letter.
  ///
  /// A negative value can be used to bring the letters closer.
  ///
  /// This value takes precedence over any text letter spacing specified at the
  /// application level. For example, at framework level, in the [TextStyle]
  /// for [Text], [SelectableText], and [EditableText] widgets, this value
  /// overrides the existing value of [TextStyle.letterSpacing].
  ///
  /// Returns null when no override has been set by the system.
  ///
  /// Defaults to the value provided by [PlatformDispatcher.letterSpacingOverride].
  /// This can only be set in a test environment to emulate different platform
  /// configurations. A standard [PlatformDispatcher] is not mutable from the
  /// framework.
  ///
  /// Setting this value to `null` will force [letterSpacingOverride] to return
  /// `null`. If you want to have the value default to the platform
  /// [letterSpacingOverride], use [clearLetterSpacingOverrideTestValue].
  ///
  /// See also:
  ///
  ///   * [PlatformDispatcher.letterSpacingOverride] for the standard implementation
  ///   * [clearLetterSpacingOverrideTestValue] to reset this value specifically
  ///   * [clearAllTestValues] to reset all test values for this view
  @override
  double? get letterSpacingOverride => _forceLetterSpacingOverrideToBeNull
      ? null
      : _letterSpacingOverrideTestValue ?? _platformDispatcher.letterSpacingOverride;
  double? _letterSpacingOverrideTestValue;
  bool _forceLetterSpacingOverrideToBeNull = false;

  /// Hides the real letter spacing and reports the given
  /// [letterSpacingOverrideTestValue] instead.
  /// ignore: avoid_setters_without_getters
  set letterSpacingOverrideTestValue(double? letterSpacingOverrideTestValue) {
    _letterSpacingOverrideTestValue = letterSpacingOverrideTestValue;
    if (letterSpacingOverrideTestValue == null) {
      _forceLetterSpacingOverrideToBeNull = true;
    }
    onMetricsChanged?.call();
  }

  /// Deletes any existing test letter spacing and returns to using the real
  /// letter spacing.
  void clearLetterSpacingOverrideTestValue() {
    _letterSpacingOverrideTestValue = null;
    _forceLetterSpacingOverrideToBeNull = false;
    onMetricsChanged?.call();
  }

  /// The system-suggested amount of additional space (in logical pixels)
  /// to add between each sequence of white-space (i.e. between each word).
  ///
  /// A negative value can be used to bring the words closer.
  ///
  /// This value takes precedence over any text word spacing specified at the
  /// application level. For example, at framework level, in the [TextStyle]
  /// for [Text], [SelectableText], and [EditableText] widgets, this value
  /// overrides the existing value of [TextStyle.wordSpacing].
  ///
  /// Returns null when no override has been set by the system.
  ///
  /// Defaults to the value provided by [PlatformDispatcher.wordSpacingOverride].
  /// This can only be set in a test environment to emulate different platform
  /// configurations. A standard [PlatformDispatcher] is not mutable from the
  /// framework.
  ///
  /// Setting this value to `null` will force [wordSpacingOverride] to return
  /// `null`. If you want to have the value default to the platform
  /// [wordSpacingOverride], use [clearWordSpacingOverrideTestValue].
  ///
  /// See also:
  ///
  ///   * [PlatformDispatcher.wordSpacingOverride] for the standard implementation
  ///   * [clearWordSpacingOverrideTestValue] to reset this value specifically
  ///   * [clearAllTestValues] to reset all test values for this view
  @override
  double? get wordSpacingOverride => _forceWordSpacingOverrideToBeNull
      ? null
      : _wordSpacingOverrideTestValue ?? _platformDispatcher.wordSpacingOverride;
  double? _wordSpacingOverrideTestValue;
  bool _forceWordSpacingOverrideToBeNull = false;

  /// Hides the real word spacing and reports the given
  /// [wordSpacingOverrideTestValue] instead.
  /// ignore: avoid_setters_without_getters
  set wordSpacingOverrideTestValue(double? wordSpacingOverrideTestValue) {
    _wordSpacingOverrideTestValue = wordSpacingOverrideTestValue;
    if (wordSpacingOverrideTestValue == null) {
      _forceWordSpacingOverrideToBeNull = true;
    }
    onMetricsChanged?.call();
  }

  /// Deletes any existing test word spacing and returns to using the real
  /// word spacing.
  void clearWordSpacingOverrideTestValue() {
    _wordSpacingOverrideTestValue = null;
    _forceWordSpacingOverrideToBeNull = false;
    onMetricsChanged?.call();
  }

  /// The system-suggested amount of additional space (in logical pixels)
  /// to add following each paragraph in text.
  ///
  /// This value takes precedence over any text paragraph spacing specified at
  /// the application level.
  ///
  /// Returns null when no override has been set by the system.
  ///
  /// Defaults to the value provided by [PlatformDispatcher.paragraphSpacingOverride].
  /// This can only be set in a test environment to emulate different platform
  /// configurations. A standard [PlatformDispatcher] is not mutable from the
  /// framework.
  ///
  /// Setting this value to `null` will force [paragraphSpacingOverride] to return
  /// `null`. If you want to have the value default to the platform
  /// [paragraphSpacingOverride], use [clearParagraphSpacingOverrideTestValue].
  ///
  /// See also:
  ///
  ///   * [PlatformDispatcher.paragraphSpacingOverride] for the standard implementation
  ///   * [clearParagraphSpacingOverrideTestValue] to reset this value specifically
  ///   * [clearAllTestValues] to reset all test values for this view
  @override
  double? get paragraphSpacingOverride => _forceParagraphSpacingOverrideToBeNull
      ? null
      : _paragraphSpacingOverrideTestValue ?? _platformDispatcher.paragraphSpacingOverride;
  double? _paragraphSpacingOverrideTestValue;
  bool _forceParagraphSpacingOverrideToBeNull = false;

  /// Hides the real paragraph spacing and reports the given
  /// [paragraphSpacingOverrideTestValue] instead.
  /// ignore: avoid_setters_without_getters
  set paragraphSpacingOverrideTestValue(double? paragraphSpacingOverrideTestValue) {
    _paragraphSpacingOverrideTestValue = paragraphSpacingOverrideTestValue;
    if (paragraphSpacingOverrideTestValue == null) {
      _forceParagraphSpacingOverrideToBeNull = true;
    }
    onMetricsChanged?.call();
  }

  /// Deletes any existing test paragraph spacing and returns to using the real
  /// paragraph spacing.
  void clearParagraphSpacingOverrideTestValue() {
    _paragraphSpacingOverrideTestValue = null;
    _forceParagraphSpacingOverrideToBeNull = false;
    onMetricsChanged?.call();
  }

  @override
  FrameCallback? get onBeginFrame => _platformDispatcher.onBeginFrame;
  @override
  set onBeginFrame(FrameCallback? callback) {
    _platformDispatcher.onBeginFrame = callback;
  }

  @override
  VoidCallback? get onDrawFrame => _platformDispatcher.onDrawFrame;
  @override
  set onDrawFrame(VoidCallback? callback) {
    _platformDispatcher.onDrawFrame = callback;
  }

  @override
  TimingsCallback? get onReportTimings => _platformDispatcher.onReportTimings;
  @override
  set onReportTimings(TimingsCallback? callback) {
    _platformDispatcher.onReportTimings = callback;
  }

  @override
  PointerDataPacketCallback? get onPointerDataPacket => _platformDispatcher.onPointerDataPacket;
  @override
  set onPointerDataPacket(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.
  // ignore: avoid_setters_without_getters
  set defaultRouteNameTestValue(String defaultRouteNameTestValue) {
    _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;

  /// The application locale set during the test.
  Locale? applicationLocale;

  @override
  void setApplicationLocale(Locale locale) {
    applicationLocale = locale;
  }

  /// Hides the real semantics enabled and reports the given
  /// [semanticsEnabledTestValue] instead.
  // ignore: avoid_setters_without_getters
  set semanticsEnabledTestValue(bool semanticsEnabledTestValue) {
    _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
  VoidCallback? get onSemanticsEnabledChanged => _platformDispatcher.onSemanticsEnabledChanged;
  @override
  set onSemanticsEnabledChanged(VoidCallback? callback) {
    _platformDispatcher.onSemanticsEnabledChanged = callback;
  }

  @override
  SemanticsActionEventCallback? get onSemanticsActionEvent =>
      _platformDispatcher.onSemanticsActionEvent;
  @override
  set onSemanticsActionEvent(SemanticsActionEventCallback? callback) {
    _platformDispatcher.onSemanticsActionEvent = callback;
  }

  @override
  AccessibilityFeatures get accessibilityFeatures =>
      _accessibilityFeaturesTestValue ?? _platformDispatcher.accessibilityFeatures;
  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.
  // ignore: avoid_setters_without_getters
  set accessibilityFeaturesTestValue(AccessibilityFeatures accessibilityFeaturesTestValue) {
    _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
  VoidCallback? get onAccessibilityFeaturesChanged =>
      _platformDispatcher.onAccessibilityFeaturesChanged;
  @override
  set onAccessibilityFeaturesChanged(VoidCallback? callback) {
    _platformDispatcher.onAccessibilityFeaturesChanged = callback;
  }

  @override
  void setIsolateDebugName(String name) {
    _platformDispatcher.setIsolateDebugName(name);
  }

  @override
  void sendPlatformMessage(String name, ByteData? data, PlatformMessageResponseCallback? callback) {
    _platformDispatcher.sendPlatformMessage(name, data, callback);
  }

  /// Delete any test value properties that have been set on this [TestPlatformDispatcher]
  /// and return to reporting the real [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();
    clearNativeSpellCheckServiceDefined();
    clearLineHeightScaleFactorOverrideTestValue();
    clearLetterSpacingOverrideTestValue();
    clearWordSpacingOverrideTestValue();
    clearParagraphSpacingOverrideTestValue();
    resetBrieflyShowPassword();
    resetSupportsShowingSystemContextMenu();
    resetInitialLifecycleState();
    resetSystemFontFamily();
  }

  @override
  VoidCallback? get onFrameDataChanged => _platformDispatcher.onFrameDataChanged;
  @override
  set onFrameDataChanged(VoidCallback? value) {
    _platformDispatcher.onFrameDataChanged = value;
  }

  @override
  KeyDataCallback? get onKeyData => _platformDispatcher.onKeyData;

  @override
  set onKeyData(KeyDataCallback? onKeyData) {
    _platformDispatcher.onKeyData = onKeyData;
  }

  @override
  VoidCallback? get onPlatformConfigurationChanged =>
      _platformDispatcher.onPlatformConfigurationChanged;

  @override
  set onPlatformConfigurationChanged(VoidCallback? onPlatformConfigurationChanged) {
    _platformDispatcher.onPlatformConfigurationChanged = onPlatformConfigurationChanged;
  }

  @override
  Locale? computePlatformResolvedLocale(List<Locale> supportedLocales) =>
      _platformDispatcher.computePlatformResolvedLocale(supportedLocales);

  @override
  ByteData? getPersistentIsolateData() => _platformDispatcher.getPersistentIsolateData();

  @override
  Iterable<TestFlutterView> get views => _testViews.values;

  @override
  FlutterView? view({required int id}) => _testViews[id];

  @override
  Iterable<TestDisplay> get displays => _testDisplays.values;

  void _updateViewsAndDisplays() {
    final extraDisplayKeys = <Object>[..._testDisplays.keys];
    for (final Display display in _platformDispatcher.displays) {
      extraDisplayKeys.remove(display.id);
      if (!_testDisplays.containsKey(display.id)) {
        _testDisplays[display.id] = TestDisplay(this, display);
      }
    }
    extraDisplayKeys.forEach(_testDisplays.remove);

    final extraViewKeys = <Object>[..._testViews.keys];
    for (final FlutterView view in _platformDispatcher.views) {
      // TODO(pdblasi-google): Remove this try-catch once the Display API is stable and supported on all platforms
      late final TestDisplay display;
      try {
        final Display realDisplay = view.display;
        if (_testDisplays.containsKey(realDisplay.id)) {
          display = _testDisplays[view.display.id]!;
        } else {
          display = _UnsupportedDisplay(
            this,
            view,
            'PlatformDispatcher did not contain a Display with id ${realDisplay.id}, '
            'which was expected by FlutterView ($view)',
          );
        }
      } catch (error) {
        display = _UnsupportedDisplay(this, view, error);
      }

      extraViewKeys.remove(view.viewId);
      if (!_testViews.containsKey(view.viewId)) {
        _testViews[view.viewId] = TestFlutterView(
          view: view,
          platformDispatcher: this,
          display: display,
        );
      }
    }

    extraViewKeys.forEach(_testViews.remove);
  }

  /// Adds a [TestFlutterView] that wraps the given [view] to the list of views
  /// managed by this [TestPlatformDispatcher].
  ///
  /// The added view will be associated with the first display in the list of
  /// displays managed by this [TestPlatformDispatcher].
  void addTestView(FlutterView view) {
    _testViews[view.viewId] = TestFlutterView(
      view: view,
      platformDispatcher: this,
      display: displays.first,
    );
    _updateViewsAndDisplays();
  }

  @override
  ErrorCallback? get onError => _platformDispatcher.onError;
  @override
  set onError(ErrorCallback? value) {
    _platformDispatcher.onError;
  }

  @override
  VoidCallback? get onSystemFontFamilyChanged => _platformDispatcher.onSystemFontFamilyChanged;
  @override
  set onSystemFontFamilyChanged(VoidCallback? value) {
    _platformDispatcher.onSystemFontFamilyChanged = value;
  }

  @override
  FrameData get frameData => _platformDispatcher.frameData;

  @override
  void registerBackgroundIsolate(RootIsolateToken token) {
    _platformDispatcher.registerBackgroundIsolate(token);
  }

  @override
  void requestDartPerformanceMode(DartPerformanceMode mode) {
    _platformDispatcher.requestDartPerformanceMode(mode);
  }

  /// The system font family to use for this test.
  ///
  /// Defaults to the value provided by [PlatformDispatcher.systemFontFamily].
  /// This can only be set in a test environment to emulate different platform
  /// configurations. A standard [PlatformDispatcher] is not mutable from the
  /// framework.
  ///
  /// Setting this value to `null` will force [systemFontFamily] to return
  /// `null`. If you want to have the value default to the platform
  /// [systemFontFamily], use [resetSystemFontFamily].
  ///
  /// See also:
  ///
  ///   * [PlatformDispatcher.systemFontFamily] for the standard implementation
  ///   * [resetSystemFontFamily] to reset this value specifically
  ///   * [clearAllTestValues] to reset all test values for this view
  @override
  String? get systemFontFamily {
    return _forceSystemFontFamilyToBeNull
        ? null
        : _systemFontFamily ?? _platformDispatcher.systemFontFamily;
  }

  String? _systemFontFamily;
  bool _forceSystemFontFamilyToBeNull = false;
  set systemFontFamily(String? value) {
    _systemFontFamily = value;
    if (value == null) {
      _forceSystemFontFamilyToBeNull = true;
    }
    onSystemFontFamilyChanged?.call();
  }

  /// Resets [systemFontFamily] to the default for the platform.
  void resetSystemFontFamily() {
    _systemFontFamily = null;
    _forceSystemFontFamilyToBeNull = false;
    onSystemFontFamilyChanged?.call();
  }

  @override
  void updateSemantics(SemanticsUpdate update) {
    _platformDispatcher.updateSemantics(update);
  }

  /// 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;
  }
}

/// A [FlutterView] that wraps another [FlutterView] and allows faking of
/// some properties for testing purposes.
///
/// This class should not be instantiated manually, as
/// it requires a backing [FlutterView] that must be produced from
/// a [PlatformDispatcher].
///
/// See also:
///
///   * [WidgetTester.view] which allows for accessing the [TestFlutterView]
///     for single view applications or widget testing.
///   * [WidgetTester.viewOf] which allows for accessing the appropriate
///     [TestFlutterView] in a given situation for multi-view applications.
///   * [TestPlatformDispatcher], which allows for faking of platform specific
///     functionality.
class TestFlutterView implements FlutterView {
  /// Constructs a [TestFlutterView] that defers all behavior to the given
  /// [FlutterView] unless explicitly overridden for testing.
  TestFlutterView({
    required FlutterView view,
    required TestPlatformDispatcher platformDispatcher,
    required TestDisplay display,
  }) : _view = view,
       _platformDispatcher = platformDispatcher,
       _display = display;

  /// The [FlutterView] backing this [TestFlutterView].
  final FlutterView _view;

  @override
  TestPlatformDispatcher get platformDispatcher => _platformDispatcher;
  final TestPlatformDispatcher _platformDispatcher;

  @override
  TestDisplay get display => _display;
  final TestDisplay _display;

  @override
  int get viewId => _view.viewId;

  /// The device pixel ratio to use for this test.
  ///
  /// Defaults to the value provided by [FlutterView.devicePixelRatio]. This
  /// can only be set in a test environment to emulate different view
  /// configurations. A standard [FlutterView] is not mutable from the framework.
  ///
  /// See also:
  ///
  ///   * [FlutterView.devicePixelRatio] for the standard implementation
  ///   * [TestDisplay.devicePixelRatio] which will stay in sync with this value
  ///   * [resetDevicePixelRatio] to reset this value specifically
  ///   * [reset] to reset all test values for this view
  @override
  double get devicePixelRatio => _display._devicePixelRatio ?? _view.devicePixelRatio;
  set devicePixelRatio(double value) {
    _display.devicePixelRatio = value;
  }

  /// Resets [devicePixelRatio] for this test view to the default value for this view.
  ///
  /// This will also reset the [devicePixelRatio] for the [TestDisplay]
  /// that is related to this view.
  void resetDevicePixelRatio() {
    _display.resetDevicePixelRatio();
  }

  /// The display features to use for this test.
  ///
  /// Defaults to the value provided by [FlutterView.displayFeatures]. This
  /// can only be set in a test environment to emulate different view
  /// configurations. A standard [FlutterView] is not mutable from the framework.
  ///
  /// See also:
  ///
  ///   * [FlutterView.displayFeatures] for the standard implementation
  ///   * [resetDisplayFeatures] to reset this value specifically
  ///   * [reset] to reset all test values for this view
  @override
  List<DisplayFeature> get displayFeatures => _displayFeatures ?? _view.displayFeatures;
  List<DisplayFeature>? _displayFeatures;
  set displayFeatures(List<DisplayFeature> value) {
    _displayFeatures = value;
    platformDispatcher.onMetricsChanged?.call();
  }

  /// Resets [displayFeatures] to the default values for this view.
  void resetDisplayFeatures() {
    _displayFeatures = null;
    platformDispatcher.onMetricsChanged?.call();
  }

  /// The padding to use for this test.
  ///
  /// Defaults to the value provided by [FlutterView.padding]. This
  /// can only be set in a test environment to emulate different view
  /// configurations. A standard [FlutterView] is not mutable from the framework.
  ///
  /// See also:
  ///
  ///   * [FakeViewPadding] which is used to set this value for testing
  ///   * [FlutterView.padding] for the standard implementation.
  ///   * [resetPadding] to reset this value specifically.
  ///   * [reset] to reset all test values for this view.
  @override
  FakeViewPadding get padding => _padding ?? FakeViewPadding._wrap(_view.padding);
  FakeViewPadding? _padding;
  set padding(FakeViewPadding value) {
    _padding = value;
    platformDispatcher.onMetricsChanged?.call();
  }

  /// Resets [padding] to the default value for this view.
  void resetPadding() {
    _padding = null;
    platformDispatcher.onMetricsChanged?.call();
  }

  /// The physical size to use for this test.
  ///
  /// Defaults to the value provided by [FlutterView.physicalSize]. This
  /// can only be set in a test environment to emulate different view
  /// configurations. A standard [FlutterView] is not mutable from the framework.
  ///
  /// Setting this value also sets [physicalConstraints] to tight constraints
  /// based on the given size.
  ///
  /// See also:
  ///
  ///   * [FlutterView.physicalSize] for the standard implementation
  ///   * [resetPhysicalSize] to reset this value specifically
  ///   * [reset] to reset all test values for this view
  @override
  Size get physicalSize => _physicalSize ?? _view.physicalSize;
  Size? _physicalSize;
  set physicalSize(Size value) {
    _physicalSize = value;
    // For backwards compatibility the constraints are set based on the provided size.
    physicalConstraints = ViewConstraints.tight(value);
  }

  /// Resets [physicalSize] (and implicitly also the [physicalConstraints]) to
  /// the default value for this view.
  void resetPhysicalSize() {
    _physicalSize = null;
    resetPhysicalConstraints();
  }

  /// The physical constraints to use for this test.
  ///
  /// Defaults to the value provided by [FlutterView.physicalConstraints]. This
  /// can only be set in a test environment to emulate different view
  /// configurations. A standard [FlutterView] is not mutable from the framework.
  ///
  /// See also:
  ///
  ///   * [FlutterView.physicalConstraints] for the standard implementation
  ///   * [physicalConstraints] to reset this value specifically
  ///   * [reset] to reset all test values for this view
  @override
  ViewConstraints get physicalConstraints => _physicalConstraints ?? _view.physicalConstraints;
  ViewConstraints? _physicalConstraints;
  set physicalConstraints(ViewConstraints value) {
    _physicalConstraints = value;
    platformDispatcher.onMetricsChanged?.call();
  }

  /// Resets [physicalConstraints] to the default value for this view.
  void resetPhysicalConstraints() {
    _physicalConstraints = null;
    platformDispatcher.onMetricsChanged?.call();
  }

  /// The system gesture insets to use for this test.
  ///
  /// Defaults to the value provided by [FlutterView.systemGestureInsets].
  /// This can only be set in a test environment to emulate different view
  /// configurations. A standard [FlutterView] is not mutable from the framework.
  ///
  /// See also:
  ///
  ///   * [FakeViewPadding] which is used to set this value for testing
  ///   * [FlutterView.systemGestureInsets] for the standard implementation
  ///   * [resetSystemGestureInsets] to reset this value specifically
  ///   * [reset] to reset all test values for this view
  @override
  FakeViewPadding get systemGestureInsets =>
      _systemGestureInsets ?? FakeViewPadding._wrap(_view.systemGestureInsets);
  FakeViewPadding? _systemGestureInsets;
  set systemGestureInsets(FakeViewPadding value) {
    _systemGestureInsets = value;
    platformDispatcher.onMetricsChanged?.call();
  }

  /// Resets [systemGestureInsets] to the default value for this view.
  void resetSystemGestureInsets() {
    _systemGestureInsets = null;
    platformDispatcher.onMetricsChanged?.call();
  }

  /// The view insets to use for this test.
  ///
  /// Defaults to the value provided by [FlutterView.viewInsets]. This
  /// can only be set in a test environment to emulate different view
  /// configurations. A standard [FlutterView] is not mutable from the framework.
  ///
  /// See also:
  ///
  ///   * [FakeViewPadding] which is used to set this value for testing
  ///   * [FlutterView.viewInsets] for the standard implementation
  ///   * [resetViewInsets] to reset this value specifically
  ///   * [reset] to reset all test values for this view
  @override
  FakeViewPadding get viewInsets => _viewInsets ?? FakeViewPadding._wrap(_view.viewInsets);
  FakeViewPadding? _viewInsets;
  set viewInsets(FakeViewPadding value) {
    _viewInsets = value;
    platformDispatcher.onMetricsChanged?.call();
  }

  /// Resets [viewInsets] to the default value for this view.
  void resetViewInsets() {
    _viewInsets = null;
    platformDispatcher.onMetricsChanged?.call();
  }

  /// The view padding to use for this test.
  ///
  /// Defaults to the value provided by [FlutterView.viewPadding]. This
  /// can only be set in a test environment to emulate different view
  /// configurations. A standard [FlutterView] is not mutable from the framework.
  ///
  /// See also:
  ///
  ///   * [FakeViewPadding] which is used to set this value for testing
  ///   * [FlutterView.viewPadding] for the standard implementation
  ///   * [resetViewPadding] to reset this value specifically
  ///   * [reset] to reset all test values for this view
  @override
  FakeViewPadding get viewPadding => _viewPadding ?? FakeViewPadding._wrap(_view.viewPadding);
  FakeViewPadding? _viewPadding;
  set viewPadding(FakeViewPadding value) {
    _viewPadding = value;
    platformDispatcher.onMetricsChanged?.call();
  }

  /// Resets [viewPadding] to the default value for this view.
  void resetViewPadding() {
    _viewPadding = null;
    platformDispatcher.onMetricsChanged?.call();
  }

  /// The gesture settings to use for this test.
  ///
  /// Defaults to the value provided by [FlutterView.gestureSettings]. This
  /// can only be set in a test environment to emulate different view
  /// configurations. A standard [FlutterView] is not mutable from the framework.
  ///
  /// See also:
  ///
  ///   * [FlutterView.gestureSettings] for the standard implementation
  ///   * [resetGestureSettings] to reset this value specifically
  ///   * [reset] to reset all test values for this view
  @override
  GestureSettings get gestureSettings => _gestureSettings ?? _view.gestureSettings;
  GestureSettings? _gestureSettings;
  set gestureSettings(GestureSettings value) {
    _gestureSettings = value;
    platformDispatcher.onMetricsChanged?.call();
  }

  /// Resets [gestureSettings] to the default value for this view.
  void resetGestureSettings() {
    _gestureSettings = null;
    platformDispatcher.onMetricsChanged?.call();
  }

  @override
  void render(Scene scene, {Size? size}) {
    _view.render(scene, size: size);
  }

  @override
  void updateSemantics(SemanticsUpdate update) {
    _view.updateSemantics(update);
  }

  /// Resets all test values to the defaults for this view.
  ///
  /// See also:
  ///
  ///   * [resetDevicePixelRatio] to reset [devicePixelRatio] specifically
  ///   * [resetDisplayFeatures]  to reset [displayFeatures] specifically
  ///   * [resetPadding] to reset [padding] specifically
  ///   * [resetPhysicalSize] to reset [physicalSize] specifically
  ///   * [resetSystemGestureInsets] to reset [systemGestureInsets] specifically
  ///   * [resetViewInsets] to reset [viewInsets] specifically
  ///   * [resetViewPadding] to reset [viewPadding] specifically
  ///   * [resetGestureSettings] to reset [gestureSettings] specifically
  void reset() {
    resetDevicePixelRatio();
    resetDisplayFeatures();
    resetPadding();
    resetPhysicalSize();
    // resetPhysicalConstraints is implicitly called by resetPhysicalSize.
    resetSystemGestureInsets();
    resetViewInsets();
    resetViewPadding();
    resetGestureSettings();
  }

  /// This gives us some grace time when the dart:ui side adds something to
  /// [FlutterView], and makes things easier when we do rolls to give
  /// us time to catch up.
  @override
  dynamic noSuchMethod(Invocation invocation) {
    return null;
  }
}

/// A version of [Display] that can be modified to allow for testing various
/// use cases.
///
/// Updates to the [TestDisplay] will be surfaced through
/// [PlatformDispatcher.onMetricsChanged].
class TestDisplay implements Display {
  /// Creates a new [TestDisplay] backed by the given [Display].
  TestDisplay(TestPlatformDispatcher platformDispatcher, Display display)
    : _platformDispatcher = platformDispatcher,
      _display = display;

  final Display _display;
  final TestPlatformDispatcher _platformDispatcher;

  @override
  int get id => _display.id;

  /// The device pixel ratio to use for this test.
  ///
  /// Defaults to the value provided by [Display.devicePixelRatio]. This
  /// can only be set in a test environment to emulate different display
  /// configurations. A standard [Display] is not mutable from the framework.
  ///
  /// See also:
  ///
  ///   * [Display.devicePixelRatio] for the standard implementation
  ///   * [TestFlutterView.devicePixelRatio] which will stay in sync with this value
  ///   * [resetDevicePixelRatio] to reset this value specifically
  ///   * [reset] to reset all test values for this display
  @override
  double get devicePixelRatio => _devicePixelRatio ?? _display.devicePixelRatio;
  double? _devicePixelRatio;
  set devicePixelRatio(double value) {
    _devicePixelRatio = value;
    _platformDispatcher.onMetricsChanged?.call();
  }

  /// Resets [devicePixelRatio] to the default value for this display.
  ///
  /// This will also reset the [devicePixelRatio] for any [TestFlutterView]s
  /// that are related to this display.
  void resetDevicePixelRatio() {
    _devicePixelRatio = null;
    _platformDispatcher.onMetricsChanged?.call();
  }

  /// The refresh rate to use for this test.
  ///
  /// Defaults to the value provided by [Display.refreshRate]. This
  /// can only be set in a test environment to emulate different display
  /// configurations. A standard [Display] is not mutable from the framework.
  ///
  /// See also:
  ///
  ///   * [Display.refreshRate] for the standard implementation
  ///   * [resetRefreshRate] to reset this value specifically
  ///   * [reset] to reset all test values for this display
  @override
  double get refreshRate => _refreshRate ?? _display.refreshRate;
  double? _refreshRate;
  set refreshRate(double value) {
    _refreshRate = value;
    _platformDispatcher.onMetricsChanged?.call();
  }

  /// Resets [refreshRate] to the default value for this display.
  void resetRefreshRate() {
    _refreshRate = null;
    _platformDispatcher.onMetricsChanged?.call();
  }

  /// The size of the [Display] to use for this test.
  ///
  /// Defaults to the value provided by [Display.refreshRate]. This
  /// can only be set in a test environment to emulate different display
  /// configurations. A standard [Display] is not mutable from the framework.
  ///
  /// See also:
  ///
  ///   * [Display.refreshRate] for the standard implementation
  ///   * [resetRefreshRate] to reset this value specifically
  ///   * [reset] to reset all test values for this display
  @override
  Size get size => _size ?? _display.size;
  Size? _size;
  set size(Size value) {
    _size = value;
    _platformDispatcher.onMetricsChanged?.call();
  }

  /// Resets [size] to the default value for this display.
  void resetSize() {
    _size = null;
    _platformDispatcher.onMetricsChanged?.call();
  }

  /// Resets all values on this [TestDisplay].
  ///
  /// See also:
  ///   * [resetDevicePixelRatio] to reset [devicePixelRatio] specifically
  ///   * [resetRefreshRate] to reset [refreshRate] specifically
  ///   * [resetSize] to reset [size] specifically
  void reset() {
    resetDevicePixelRatio();
    resetRefreshRate();
    resetSize();
  }

  /// This gives us some grace time when the dart:ui side adds something to
  /// [Display], and makes things easier when we do rolls to give
  /// us time to catch up.
  @override
  dynamic noSuchMethod(Invocation invocation) {
    return null;
  }
}

// TODO(pdblasi-google): Remove this once the Display API is stable and supported on all platforms
class _UnsupportedDisplay implements TestDisplay {
  _UnsupportedDisplay(this._platformDispatcher, this._view, this.error);

  final FlutterView _view;
  final Object? error;

  @override
  final TestPlatformDispatcher _platformDispatcher;

  @override
  double get devicePixelRatio => _devicePixelRatio ?? _view.devicePixelRatio;
  @override
  double? _devicePixelRatio;
  @override
  set devicePixelRatio(double value) {
    _devicePixelRatio = value;
    _platformDispatcher.onMetricsChanged?.call();
  }

  @override
  void resetDevicePixelRatio() {
    _devicePixelRatio = null;
    _platformDispatcher.onMetricsChanged?.call();
  }

  @override
  dynamic noSuchMethod(Invocation invocation) {
    throw UnsupportedError(
      'The Display API is unsupported in this context. '
      'As of the last metrics change on PlatformDispatcher, this was the error '
      'given when trying to prepare the display for testing: $error',
    );
  }
}

/// Deprecated. Will be removed in a future version of Flutter.
///
/// This class has been deprecated to prepare for Flutter's upcoming support
/// for multiple views and multiple windows.
///
/// [SingletonFlutterWindow] that wraps another [SingletonFlutterWindow] and
/// allows faking of some properties for testing purposes.
///
/// Tests for certain widgets, e.g., [MaterialApp], might require faking certain
/// properties of a [SingletonFlutterWindow]. [TestWindow] facilitates the
/// faking of these properties by overriding the properties of a real
/// [SingletonFlutterWindow] with desired fake values. The binding used within
/// tests, [TestWidgetsFlutterBinding], contains a [TestWindow] that is used by
/// all tests.
///
/// ## Sample Code
///
/// A test can utilize a [TestWindow] in the following way:
///
/// ```dart
/// testWidgets('your test name here', (WidgetTester tester) async {
///   // Retrieve the TestWidgetsFlutterBinding.
///   final TestWidgetsFlutterBinding testBinding = tester.binding;
///
///   // Fake the desired properties of the TestWindow. All code running
///   // within this test will perceive the following fake text scale
///   // factor as the real text scale factor of the window.
///   testBinding.platformDispatcher.textScaleFactorTestValue = 2.5;
///
///   // Test code that depends on text scale factor here.
/// });
/// ```
///
/// The [TestWidgetsFlutterBinding] is recreated for each test and
/// therefore any fake values defined in one test will not persist
/// to the next.
///
/// If a test needs to override a real [SingletonFlutterWindow] property and
/// then later return to using the real [SingletonFlutterWindow] property,
/// [TestWindow] provides methods to clear each individual test value, e.g.,
/// [clearDevicePixelRatioTestValue].
///
/// 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.
@Deprecated(
  'Use TestPlatformDispatcher (via WidgetTester.platformDispatcher) or TestFlutterView (via WidgetTester.view) instead. '
  'Deprecated to prepare for the upcoming multi-window support. '
  'This feature was deprecated after v3.9.0-0.1.pre.',
)
class TestWindow implements SingletonFlutterWindow {
  /// Constructs a [TestWindow] that defers all behavior to the given
  /// [SingletonFlutterWindow] unless explicitly overridden for test purposes.
  @Deprecated(
    'Use TestPlatformDispatcher (via WidgetTester.platformDispatcher) or TestFlutterView (via WidgetTester.view) instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  TestWindow({required SingletonFlutterWindow window})
    : platformDispatcher = TestPlatformDispatcher(platformDispatcher: window.platformDispatcher);

  /// Constructs a [TestWindow] that defers all behavior to the given
  /// [TestPlatformDispatcher] and its [TestPlatformDispatcher.implicitView].
  ///
  /// This class will not work when multiple views are present. If multiple view
  /// support is needed use [WidgetTester.platformDispatcher] and
  /// [WidgetTester.viewOf].
  ///
  /// See also:
  ///
  ///   * [TestPlatformDispatcher] which allows faking of platform-wide values for
  ///     testing purposes.
  ///   * [TestFlutterView] which allows faking of view-specific values for
  ///     testing purposes.
  @Deprecated(
    'Use TestPlatformDispatcher (via WidgetTester.platformDispatcher) or TestFlutterView (via WidgetTester.view) instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  TestWindow.fromPlatformDispatcher({
    @Deprecated(
      'Use WidgetTester.platformDispatcher instead. '
      'Deprecated to prepare for the upcoming multi-window support. '
      'This feature was deprecated after v3.9.0-0.1.pre.',
    )
    required this.platformDispatcher,
  });

  @Deprecated(
    'Use WidgetTester.platformDispatcher instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  final TestPlatformDispatcher platformDispatcher;

  TestFlutterView get _view => platformDispatcher.implicitView!;

  @Deprecated(
    'Use WidgetTester.view.devicePixelRatio instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  double get devicePixelRatio => _view.devicePixelRatio;

  /// Hides the real device pixel ratio and reports the given [devicePixelRatio]
  /// instead.
  @Deprecated(
    'Use WidgetTester.view.devicePixelRatio instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  // ignore: avoid_setters_without_getters
  set devicePixelRatioTestValue(double devicePixelRatio) {
    _view.devicePixelRatio = devicePixelRatio;
  }

  /// Deletes any existing test device pixel ratio and returns to using the real
  /// device pixel ratio.
  @Deprecated(
    'Use WidgetTester.view.resetDevicePixelRatio() instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  void clearDevicePixelRatioTestValue() {
    _view.resetDevicePixelRatio();
  }

  @Deprecated(
    'Use WidgetTester.view.physicalSize instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  Size get physicalSize => _view.physicalSize;

  /// Hides the real physical size and reports the given [physicalSizeTestValue]
  /// instead.
  @Deprecated(
    'Use WidgetTester.view.physicalSize instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  // ignore: avoid_setters_without_getters
  set physicalSizeTestValue(Size physicalSizeTestValue) {
    _view.physicalSize = physicalSizeTestValue;
  }

  /// Deletes any existing test physical size and returns to using the real
  /// physical size.
  @Deprecated(
    'Use WidgetTester.view.resetPhysicalSize() instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  void clearPhysicalSizeTestValue() {
    _view.resetPhysicalSize();
  }

  @Deprecated(
    'Use WidgetTester.view.viewInsets instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  ViewPadding get viewInsets => _view.viewInsets;

  /// Hides the real view insets and reports the given [viewInsetsTestValue]
  /// instead.
  ///
  /// Use [FakeViewPadding] to set this value for testing.
  @Deprecated(
    'Use WidgetTester.view.viewInsets instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  // ignore: avoid_setters_without_getters
  set viewInsetsTestValue(ViewPadding value) {
    _view.viewInsets = value is FakeViewPadding ? value : FakeViewPadding._wrap(value);
  }

  /// Deletes any existing test view insets and returns to using the real view
  /// insets.
  @Deprecated(
    'Use WidgetTester.view.resetViewInsets() instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  void clearViewInsetsTestValue() {
    _view.resetViewInsets();
  }

  @Deprecated(
    'Use WidgetTester.view.viewPadding instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  ViewPadding get viewPadding => _view.viewPadding;

  /// Hides the real view padding and reports the given [paddingTestValue]
  /// instead.
  ///
  /// Use [FakeViewPadding] to set this value for testing.
  @Deprecated(
    'Use WidgetTester.view.viewPadding instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  // ignore: avoid_setters_without_getters
  set viewPaddingTestValue(ViewPadding value) {
    _view.viewPadding = value is FakeViewPadding ? value : FakeViewPadding._wrap(value);
  }

  /// Deletes any existing test view padding and returns to using the real
  /// viewPadding.
  @Deprecated(
    'Use WidgetTester.view.resetViewPadding() instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  void clearViewPaddingTestValue() {
    _view.resetViewPadding();
  }

  @Deprecated(
    'Use WidgetTester.view.padding instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  ViewPadding get padding => _view.padding;

  /// Hides the real padding and reports the given [paddingTestValue] instead.
  ///
  /// Use [FakeViewPadding] to set this value for testing.
  @Deprecated(
    'Use WidgetTester.view.padding instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  // ignore: avoid_setters_without_getters
  set paddingTestValue(ViewPadding value) {
    _view.padding = value is FakeViewPadding ? value : FakeViewPadding._wrap(value);
  }

  /// Deletes any existing test padding and returns to using the real padding.
  @Deprecated(
    'Use WidgetTester.view.resetPadding() instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  void clearPaddingTestValue() {
    _view.resetPadding();
  }

  @Deprecated(
    'Use WidgetTester.view.gestureSettings instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  GestureSettings get gestureSettings => _view.gestureSettings;

  /// Hides the real gesture settings and reports the given [gestureSettingsTestValue] instead.
  @Deprecated(
    'Use WidgetTester.view.gestureSettings instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  // ignore: avoid_setters_without_getters
  set gestureSettingsTestValue(GestureSettings gestureSettingsTestValue) {
    _view.gestureSettings = gestureSettingsTestValue;
  }

  /// Deletes any existing test gesture settings and returns to using the real gesture settings.
  @Deprecated(
    'Use WidgetTester.view.resetGestureSettings() instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  void clearGestureSettingsTestValue() {
    _view.resetGestureSettings();
  }

  @Deprecated(
    'Use WidgetTester.view.displayFeatures instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  List<DisplayFeature> get displayFeatures => _view.displayFeatures;

  /// Hides the real displayFeatures and reports the given [displayFeaturesTestValue] instead.
  @Deprecated(
    'Use WidgetTester.view.displayFeatures instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  // ignore: avoid_setters_without_getters
  set displayFeaturesTestValue(List<DisplayFeature> displayFeaturesTestValue) {
    _view.displayFeatures = displayFeaturesTestValue;
  }

  /// Deletes any existing test padding and returns to using the real padding.
  @Deprecated(
    'Use WidgetTester.view.resetDisplayFeatures() instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  void clearDisplayFeaturesTestValue() {
    _view.resetDisplayFeatures();
  }

  @Deprecated(
    'Use WidgetTester.view.systemGestureInsets instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  ViewPadding get systemGestureInsets => _view.systemGestureInsets;

  /// Hides the real system gesture insets and reports the given
  /// [systemGestureInsetsTestValue] instead.
  ///
  /// Use [FakeViewPadding] to set this value for testing.
  @Deprecated(
    'Use WidgetTester.view.systemGestureInsets instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  // ignore: avoid_setters_without_getters
  set systemGestureInsetsTestValue(ViewPadding value) {
    _view.systemGestureInsets = value is FakeViewPadding ? value : FakeViewPadding._wrap(value);
  }

  /// Deletes any existing test system gesture insets and returns to using the real system gesture insets.
  @Deprecated(
    'Use WidgetTester.view.resetSystemGestureInsets() instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  void clearSystemGestureInsetsTestValue() {
    _view.resetSystemGestureInsets();
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.onMetricsChanged instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  VoidCallback? get onMetricsChanged => platformDispatcher.onMetricsChanged;
  @Deprecated(
    'Use WidgetTester.platformDispatcher.onMetricsChanged instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  set onMetricsChanged(VoidCallback? callback) {
    platformDispatcher.onMetricsChanged = callback;
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.locale instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  Locale get locale => platformDispatcher.locale;

  @Deprecated(
    'Use WidgetTester.platformDispatcher.locales instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  List<Locale> get locales => platformDispatcher.locales;

  @Deprecated(
    'Use WidgetTester.platformDispatcher.onLocaleChanged instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  VoidCallback? get onLocaleChanged => platformDispatcher.onLocaleChanged;
  @Deprecated(
    'Use WidgetTester.platformDispatcher.onLocaleChanged instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  set onLocaleChanged(VoidCallback? callback) {
    platformDispatcher.onLocaleChanged = callback;
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.initialLifecycleState instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  String get initialLifecycleState => platformDispatcher.initialLifecycleState;

  @Deprecated(
    'Use WidgetTester.platformDispatcher.textScaleFactor instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  double get textScaleFactor => platformDispatcher.textScaleFactor;

  @Deprecated(
    'Use WidgetTester.platformDispatcher.platformBrightness instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  Brightness get platformBrightness => platformDispatcher.platformBrightness;
  @Deprecated(
    'Use WidgetTester.platformDispatcher.onPlatformBrightnessChanged instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  VoidCallback? get onPlatformBrightnessChanged => platformDispatcher.onPlatformBrightnessChanged;
  @Deprecated(
    'Use WidgetTester.platformDispatcher.onPlatformBrightnessChanged instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  set onPlatformBrightnessChanged(VoidCallback? callback) {
    platformDispatcher.onPlatformBrightnessChanged = callback;
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.alwaysUse24HourFormat instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  bool get alwaysUse24HourFormat => platformDispatcher.alwaysUse24HourFormat;

  @Deprecated(
    'Use WidgetTester.platformDispatcher.onTextScaleFactorChanged instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  VoidCallback? get onTextScaleFactorChanged => platformDispatcher.onTextScaleFactorChanged;
  @Deprecated(
    'Use WidgetTester.platformDispatcher.onTextScaleFactorChanged instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  set onTextScaleFactorChanged(VoidCallback? callback) {
    platformDispatcher.onTextScaleFactorChanged = callback;
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.nativeSpellCheckServiceDefined instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  bool get nativeSpellCheckServiceDefined => platformDispatcher.nativeSpellCheckServiceDefined;
  @Deprecated(
    'Use WidgetTester.platformDispatcher.nativeSpellCheckServiceDefinedTestValue instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  // ignore: avoid_setters_without_getters
  set nativeSpellCheckServiceDefinedTestValue(bool nativeSpellCheckServiceDefinedTestValue) {
    platformDispatcher.nativeSpellCheckServiceDefinedTestValue =
        nativeSpellCheckServiceDefinedTestValue;
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.brieflyShowPassword instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  bool get brieflyShowPassword => platformDispatcher.brieflyShowPassword;

  @Deprecated(
    'Use WidgetTester.platformDispatcher.onBeginFrame instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  FrameCallback? get onBeginFrame => platformDispatcher.onBeginFrame;
  @Deprecated(
    'Use WidgetTester.platformDispatcher.onBeginFrame instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  set onBeginFrame(FrameCallback? callback) {
    platformDispatcher.onBeginFrame = callback;
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.onDrawFrame instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  VoidCallback? get onDrawFrame => platformDispatcher.onDrawFrame;
  @Deprecated(
    'Use WidgetTester.platformDispatcher.onDrawFrame instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  set onDrawFrame(VoidCallback? callback) {
    platformDispatcher.onDrawFrame = callback;
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.onReportTimings instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  TimingsCallback? get onReportTimings => platformDispatcher.onReportTimings;
  @Deprecated(
    'Use WidgetTester.platformDispatcher.onReportTimings instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  set onReportTimings(TimingsCallback? callback) {
    platformDispatcher.onReportTimings = callback;
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.onPointerDataPacket instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  PointerDataPacketCallback? get onPointerDataPacket => platformDispatcher.onPointerDataPacket;
  @Deprecated(
    'Use WidgetTester.platformDispatcher.onPointerDataPacket instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  set onPointerDataPacket(PointerDataPacketCallback? callback) {
    platformDispatcher.onPointerDataPacket = callback;
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.defaultRouteName instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  String get defaultRouteName => platformDispatcher.defaultRouteName;

  @Deprecated(
    'Use WidgetTester.platformDispatcher.scheduleFrame() instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  void scheduleFrame() {
    platformDispatcher.scheduleFrame();
  }

  @Deprecated(
    'Use WidgetTester.view.render(scene) instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  void render(Scene scene, {Size? size}) {
    _view.render(scene, size: size);
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.semanticsEnabled instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  bool get semanticsEnabled => platformDispatcher.semanticsEnabled;

  @Deprecated(
    'Use WidgetTester.platformDispatcher.onSemanticsEnabledChanged instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  VoidCallback? get onSemanticsEnabledChanged => platformDispatcher.onSemanticsEnabledChanged;
  @Deprecated(
    'Use WidgetTester.platformDispatcher.onSemanticsEnabledChanged instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  set onSemanticsEnabledChanged(VoidCallback? callback) {
    platformDispatcher.onSemanticsEnabledChanged = callback;
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.accessibilityFeatures instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  AccessibilityFeatures get accessibilityFeatures => platformDispatcher.accessibilityFeatures;

  @Deprecated(
    'Use WidgetTester.platformDispatcher.onAccessibilityFeaturesChanged instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  VoidCallback? get onAccessibilityFeaturesChanged =>
      platformDispatcher.onAccessibilityFeaturesChanged;
  @Deprecated(
    'Use WidgetTester.platformDispatcher.onAccessibilityFeaturesChanged instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  set onAccessibilityFeaturesChanged(VoidCallback? callback) {
    platformDispatcher.onAccessibilityFeaturesChanged = callback;
  }

  @Deprecated(
    'Use WidgetTester.view.updateSemantics(update) instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  void updateSemantics(SemanticsUpdate update) {
    _view.updateSemantics(update);
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.setIsolateDebugName(name) instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  void setIsolateDebugName(String name) {
    platformDispatcher.setIsolateDebugName(name);
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.sendPlatformMessage(name, data, callback) instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  void sendPlatformMessage(String name, ByteData? data, PlatformMessageResponseCallback? callback) {
    platformDispatcher.sendPlatformMessage(name, data, callback);
  }

  /// Delete any test value properties that have been set on this [TestWindow]
  /// as well as its [platformDispatcher].
  ///
  /// After calling this, the real [SingletonFlutterWindow] and
  /// [PlatformDispatcher] values are reported again.
  ///
  /// If desired, clearing of properties can be done on an individual basis,
  /// e.g., [clearDevicePixelRatioTestValue].
  @Deprecated(
    'Use WidgetTester.platformDispatcher.clearAllTestValues() and WidgetTester.view.reset() instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  void clearAllTestValues() {
    clearDevicePixelRatioTestValue();
    clearPaddingTestValue();
    clearGestureSettingsTestValue();
    clearDisplayFeaturesTestValue();
    clearPhysicalSizeTestValue();
    clearViewInsetsTestValue();
    platformDispatcher.clearAllTestValues();
  }

  @override
  @Deprecated(
    'Use WidgetTester.platformDispatcher.onFrameDataChanged instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  VoidCallback? get onFrameDataChanged => platformDispatcher.onFrameDataChanged;
  @Deprecated(
    'Use WidgetTester.platformDispatcher.onFrameDataChanged instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  set onFrameDataChanged(VoidCallback? value) {
    platformDispatcher.onFrameDataChanged = value;
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.onKeyData instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  KeyDataCallback? get onKeyData => platformDispatcher.onKeyData;
  @Deprecated(
    'Use WidgetTester.platformDispatcher.onKeyData instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  set onKeyData(KeyDataCallback? value) {
    platformDispatcher.onKeyData = value;
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.onSystemFontFamilyChanged instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  VoidCallback? get onSystemFontFamilyChanged => platformDispatcher.onSystemFontFamilyChanged;
  @Deprecated(
    'Use WidgetTester.platformDispatcher.onSystemFontFamilyChanged instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  set onSystemFontFamilyChanged(VoidCallback? value) {
    platformDispatcher.onSystemFontFamilyChanged = value;
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.computePlatformResolvedLocale(supportedLocales) instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  Locale? computePlatformResolvedLocale(List<Locale> supportedLocales) {
    return platformDispatcher.computePlatformResolvedLocale(supportedLocales);
  }

  @Deprecated(
    'Use WidgetTester.platformDispatcher.frameData instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  FrameData get frameData => platformDispatcher.frameData;

  @Deprecated(
    'Use WidgetTester.platformDispatcher.systemFontFamily instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  String? get systemFontFamily => platformDispatcher.systemFontFamily;

  @Deprecated(
    'Use WidgetTester.view.viewId instead. '
    'Deprecated to prepare for the upcoming multi-window support. '
    'This feature was deprecated after v3.9.0-0.1.pre.',
  )
  @override
  int get viewId => _view.viewId;

  /// This gives us some grace time when the dart:ui side adds something to
  /// [SingletonFlutterWindow], and makes things easier when we do rolls to give
  /// us time to catch up.
  @override
  dynamic noSuchMethod(Invocation invocation) {
    return null;
  }
}
