window.dart 35.2 KB
Newer Older
M
Michael Goderbauer 已提交
1
// Copyright 2013 The Flutter Authors. All rights reserved.
A
Adam Barth 已提交
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5
// @dart = 2.10
A
Adam Barth 已提交
6
part of dart.ui;
A
Adam Barth 已提交
7

8
/// A view into which a Flutter [Scene] is drawn.
9
///
10 11
/// Each [FlutterView] has its own layer tree that is rendered into an area
/// inside of a [FlutterWindow] whenever [render] is called with a [Scene].
D
Dan Field 已提交
12 13 14 15 16
///
/// ## Insets and Padding
///
/// {@animation 300 300 https://flutter.github.io/assets-for-api-docs/assets/widgets/window_padding.mp4}
///
17 18
/// In this illustration, the black areas represent system UI that the app
/// cannot draw over. The red area represents view padding that the view may not
D
Dan Field 已提交
19
/// be able to detect gestures in and may not want to draw in. The grey area
20 21
/// represents the system keyboard, which can cover over the bottom view padding
/// when visible.
D
Dan Field 已提交
22
///
23
/// The [viewInsets] are the physical pixels which the operating
D
Dan Field 已提交
24 25 26
/// system reserves for system UI, such as the keyboard, which would fully
/// obscure any content drawn in that area.
///
27 28 29 30 31 32 33 34 35
/// The [viewPadding] are the physical pixels on each side of the
/// display that may be partially obscured by system UI or by physical
/// intrusions into the display, such as an overscan region on a television or a
/// "notch" on a phone. Unlike the insets, these areas may have portions that
/// show the user view-painted pixels without being obscured, such as a
/// notch at the top of a phone that covers only a subset of the area. Insets,
/// on the other hand, either partially or fully obscure the window, such as an
/// opaque keyboard or a partially translucent status bar, which cover an area
/// without gaps.
D
Dan Field 已提交
36
///
37 38 39 40
/// The [padding] property is computed from both
/// [viewInsets] and [viewPadding]. It will allow a
/// view inset to consume view padding where appropriate, such as when a phone's
/// keyboard is covering the bottom view padding and so "absorbs" it.
D
Dan Field 已提交
41 42
///
/// Clients that want to position elements relative to the view padding
43 44 45 46
/// regardless of the view insets should use the [viewPadding]
/// property, e.g. if you wish to draw a widget at the center of the screen with
/// respect to the iPhone "safe area" regardless of whether the keyboard is
/// showing.
47
///
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
/// [padding] is useful for clients that want to know how much
/// padding should be accounted for without concern for the current inset(s)
/// state, e.g. determining whether a gesture should be considered for scrolling
/// purposes. This value varies based on the current state of the insets. For
/// example, a visible keyboard will consume all gestures in the bottom part of
/// the [viewPadding] anyway, so there is no need to account for
/// that in the [padding], which is always safe to use for such
/// calculations.
///
/// See also:
///
///  * [FlutterWindow], a special case of a [FlutterView] that is represented on
///    the platform as a separate window which can host other [FlutterView]s.
abstract class FlutterView {
  /// The platform dispatcher that this view is registered with, and gets its
  /// information from.
  PlatformDispatcher get platformDispatcher;

  /// The configuration of this view.
  ViewConfiguration get viewConfiguration;
68

69 70 71 72 73
  /// The number of device pixels for each logical pixel for the screen this
  /// view is displayed on.
  ///
  /// This number might not be a power of two. Indeed, it might not even be an
  /// integer. For example, the Nexus 6 has a device pixel ratio of 3.5.
74 75 76 77 78 79 80 81 82 83
  ///
  /// Device pixels are also referred to as physical pixels. Logical pixels are
  /// also referred to as device-independent or resolution-independent pixels.
  ///
  /// By definition, there are roughly 38 logical pixels per centimeter, or
  /// about 96 logical pixels per inch, of the physical display. The value
  /// returned by [devicePixelRatio] is ultimately obtained either from the
  /// hardware itself, the device drivers, or a hard-coded value stored in the
  /// operating system or firmware, and may be inaccurate, sometimes by a
  /// significant margin.
84 85 86 87
  ///
  /// The Flutter framework operates in logical pixels, so it is rarely
  /// necessary to directly deal with this property.
  ///
88 89
  /// When this changes, [onMetricsChanged] is called.
  ///
90 91 92 93
  /// See also:
  ///
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this value changes.
94
  double get devicePixelRatio => viewConfiguration.devicePixelRatio;
A
Adam Barth 已提交
95

96 97
  /// The dimensions and location of the rectangle into which the scene rendered
  /// in this view will be drawn on the screen, in physical pixels.
98
  ///
99 100
  /// When this changes, [onMetricsChanged] is called.
  ///
101
  /// At startup, the size and location of the view may not be known before Dart
102
  /// code runs. If this value is observed early in the application lifecycle,
103
  /// it may report [Rect.zero].
104 105 106
  ///
  /// This value does not take into account any on-screen keyboards or other
  /// system UI. The [padding] and [viewInsets] properties provide a view into
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
  /// how much of each side of the view may be obscured by system UI.
  ///
  /// See also:
  ///
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this value changes.
  Rect get physicalGeometry => viewConfiguration.geometry;

  /// The dimensions of the rectangle into which the scene rendered in this view
  /// will be drawn on the screen, in physical pixels.
  ///
  /// When this changes, [onMetricsChanged] is called.
  ///
  /// At startup, the size of the view may not be known before Dart code runs.
  /// If this value is observed early in the application lifecycle, it may
  /// report [Size.zero].
  ///
  /// This value does not take into account any on-screen keyboards or other
  /// system UI. The [padding] and [viewInsets] properties provide information
  /// about how much of each side of the view may be obscured by system UI.
  ///
  /// This value is the same as the `size` member of [physicalGeometry].
129 130 131
  ///
  /// See also:
  ///
132 133
  ///  * [physicalGeometry], which reports the location of the view as well as
  ///    its size.
134 135
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this value changes.
136
  Size get physicalSize => viewConfiguration.geometry.size;
A
Adam Barth 已提交
137 138

  /// The number of physical pixels on each side of the display rectangle into
139 140
  /// which the view can render, but over which the operating system will likely
  /// place system UI, such as the keyboard, that fully obscures any content.
141
  ///
142
  /// When this property changes, [onMetricsChanged] is called.
143
  ///
144 145 146
  /// The relationship between this [viewInsets],
  /// [viewPadding], and [padding] are described in
  /// more detail in the documentation for [FlutterView].
D
Dan Field 已提交
147
  ///
148 149 150 151 152 153 154
  /// See also:
  ///
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this value changes.
  ///  * [MediaQuery.of], a simpler mechanism for the same.
  ///  * [Scaffold], which automatically applies the view insets in material
  ///    design applications.
155
  WindowPadding get viewInsets => viewConfiguration.viewInsets;
156 157

  /// The number of physical pixels on each side of the display rectangle into
158 159 160 161
  /// which the view can render, but which may be partially obscured by system
  /// UI (such as the system notification area), or or physical intrusions in
  /// the display (e.g. overscan regions on television screens or phone sensor
  /// housings).
162
  ///
163 164 165 166
  /// Unlike [padding], this value does not change relative to
  /// [viewInsets]. For example, on an iPhone X, it will not
  /// change in response to the soft keyboard being visible or hidden, whereas
  /// [padding] will.
D
Dan Field 已提交
167
  ///
168
  /// When this property changes, [onMetricsChanged] is called.
D
Dan Field 已提交
169
  ///
170 171 172
  /// The relationship between this [viewInsets],
  /// [viewPadding], and [padding] are described in
  /// more detail in the documentation for [FlutterView].
D
Dan Field 已提交
173 174 175 176 177 178 179 180
  ///
  /// See also:
  ///
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this value changes.
  ///  * [MediaQuery.of], a simpler mechanism for the same.
  ///  * [Scaffold], which automatically applies the padding in material design
  ///    applications.
181
  WindowPadding get viewPadding => viewConfiguration.viewPadding;
D
Dan Field 已提交
182

183
  /// The number of physical pixels on each side of the display rectangle into
184 185
  /// which the view can render, but where the operating system will consume
  /// input gestures for the sake of system navigation.
186 187 188 189 190 191 192 193 194 195 196 197
  ///
  /// For example, an operating system might use the vertical edges of the
  /// screen, where swiping inwards from the edges takes users backward
  /// through the history of screens they previously visited.
  ///
  /// When this property changes, [onMetricsChanged] is called.
  ///
  /// See also:
  ///
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this value changes.
  ///  * [MediaQuery.of], a simpler mechanism for the same.
198
  WindowPadding get systemGestureInsets => viewConfiguration.systemGestureInsets;
199

D
Dan Field 已提交
200
  /// The number of physical pixels on each side of the display rectangle into
201 202 203 204 205 206 207 208 209 210 211 212
  /// which the view can render, but which may be partially obscured by system
  /// UI (such as the system notification area), or or physical intrusions in
  /// the display (e.g. overscan regions on television screens or phone sensor
  /// housings).
  ///
  /// This value is calculated by taking `max(0.0, FlutterView.viewPadding -
  /// FlutterView.viewInsets)`. This will treat a system IME that increases the
  /// bottom inset as consuming that much of the bottom padding. For example, on
  /// an iPhone X, [EdgeInsets.bottom] of [FlutterView.padding] is the same as
  /// [EdgeInsets.bottom] of [FlutterView.viewPadding] when the soft keyboard is
  /// not drawn (to account for the bottom soft button area), but will be `0.0`
  /// when the soft keyboard is visible.
D
Dan Field 已提交
213
  ///
214 215
  /// When this changes, [onMetricsChanged] is called.
  ///
216 217
  /// The relationship between this [viewInsets], [viewPadding], and [padding]
  /// are described in more detail in the documentation for [FlutterView].
D
Dan Field 已提交
218
  ///
219 220
  /// See also:
  ///
221 222 223 224 225 226
  /// * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///   observe when this value changes.
  /// * [MediaQuery.of], a simpler mechanism for the same.
  /// * [Scaffold], which automatically applies the padding in material design
  ///   applications.
  WindowPadding get padding => viewConfiguration.padding;
A
Adam Barth 已提交
227

228
  /// Updates the view's rendering on the GPU with the newly provided [Scene].
229
  ///
230 231 232
  /// This function must be called within the scope of the
  /// [PlatformDispatcher.onBeginFrame] or [PlatformDispatcher.onDrawFrame]
  /// callbacks being invoked.
233
  ///
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
  /// If this function is called a second time during a single
  /// [PlatformDispatcher.onBeginFrame]/[PlatformDispatcher.onDrawFrame]
  /// callback sequence or called outside the scope of those callbacks, the call
  /// will be ignored.
  ///
  /// To record graphical operations, first create a [PictureRecorder], then
  /// construct a [Canvas], passing that [PictureRecorder] to its constructor.
  /// After issuing all the graphical operations, call the
  /// [PictureRecorder.endRecording] function on the [PictureRecorder] to obtain
  /// the final [Picture] that represents the issued graphical operations.
  ///
  /// Next, create a [SceneBuilder], and add the [Picture] to it using
  /// [SceneBuilder.addPicture]. With the [SceneBuilder.build] method you can
  /// then obtain a [Scene] object, which you can display to the user via this
  /// [render] function.
249 250 251
  ///
  /// See also:
  ///
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
  /// * [SchedulerBinding], the Flutter framework class which manages the
  ///   scheduling of frames.
  /// * [RendererBinding], the Flutter framework class which manages layout and
  ///   painting.
  void render(Scene scene) => _render(scene, this);
  void _render(Scene scene, FlutterView view) native 'PlatformConfiguration_render';
}

/// A top-level platform window displaying a Flutter layer tree drawn from a
/// [Scene].
///
/// The current list of all Flutter views for the application is available from
/// `WidgetsBinding.instance.platformDispatcher.views`. Only views that are of type
/// [FlutterWindow] are top level platform windows.
///
/// There is also a [PlatformDispatcher.instance] singleton object in `dart:ui`
/// if `WidgetsBinding` is unavailable, but we strongly advise avoiding a static
/// reference to it. See the documentation for [PlatformDispatcher.instance] for
/// more details about why it should be avoided.
///
/// See also:
///
/// * [PlatformDispatcher], which manages the current list of [FlutterView] (and
///   thus [FlutterWindow]) instances.
class FlutterWindow extends FlutterView {
  FlutterWindow._(this._windowId, this.platformDispatcher);

  /// The opaque ID for this view.
  final Object _windowId;

  @override
  final PlatformDispatcher platformDispatcher;

  @override
  ViewConfiguration get viewConfiguration {
    assert(platformDispatcher._viewConfigurations.containsKey(_windowId));
    return platformDispatcher._viewConfigurations[_windowId]!;
  }
}

/// A [FlutterWindow] that includes access to setting callbacks and retrieving
/// properties that reside on the [PlatformDispatcher].
///
/// It is the type of the global [window] singleton used by applications that
/// only have a single main window.
///
/// In addition to the properties of [FlutterView], this class provides access
/// to platform-specific properties. To modify or retrieve these properties,
/// applications designed for more than one main window should prefer using
/// `WidgetsBinding.instance.platformDispatcher` instead.
///
/// Prefer access through `WidgetsBinding.instance.window` or
/// `WidgetsBinding.instance.platformDispatcher` over a static reference to
/// [window], or [PlatformDispatcher.instance]. See the documentation for
/// [PlatformDispatcher.instance] for more details about this recommendation.
class SingletonFlutterWindow extends FlutterWindow {
  SingletonFlutterWindow._(Object windowId, PlatformDispatcher platformDispatcher)
      : super._(windowId, platformDispatcher);

  /// A callback that is invoked whenever the [devicePixelRatio],
  /// [physicalSize], [padding], [viewInsets], [PlatformDispatcher.views], or
  /// [systemGestureInsets] values change.
  ///
315
  /// {@macro dart.ui.window.accessorForwardWarning}
316 317 318
  ///
  /// See [PlatformDispatcher.onMetricsChanged] for more information.
  VoidCallback? get onMetricsChanged => platformDispatcher.onMetricsChanged;
319
  set onMetricsChanged(VoidCallback? callback) {
320
    platformDispatcher.onMetricsChanged = callback;
Y
Yegor 已提交
321
  }
322

323 324
  /// The system-reported default locale of the device.
  ///
325
  /// {@template dart.ui.window.accessorForwardWarning}
326 327 328 329 330 331 332 333 334 335
  /// Accessing this value returns the value contained in the
  /// [PlatformDispatcher] singleton, so instead of getting it from here, you
  /// should consider getting it from `WidgetsBinding.instance.platformDispatcher` instead
  /// (or, when `WidgetsBinding` isn't available, from
  /// [PlatformDispatcher.instance]). The reason this value forwards to the
  /// [PlatformDispatcher] is to provide convenience for applications that only
  /// use a single main window.
  /// {@endtemplate}
  ///
  /// This establishes the language and formatting conventions that window
336 337
  /// should, if possible, use to render their user interface.
  ///
338 339
  /// This is the first locale selected by the user and is the user's primary
  /// locale (the locale the device UI is displayed in)
340
  ///
341 342
  /// This is equivalent to `locales.first` and will provide an empty non-null
  /// locale if the [locales] list has not been set or is empty.
343
  Locale get locale => platformDispatcher.locale;
344 345

  /// The full system-reported supported locales of the device.
346
  ///
347
  /// {@macro dart.ui.window.accessorForwardWarning}
348 349
  ///
  /// This establishes the language and formatting conventions that window
350 351
  /// should, if possible, use to render their user interface.
  ///
352 353 354
  /// The list is ordered in order of priority, with lower-indexed locales being
  /// preferred over higher-indexed ones. The first element is the primary [locale].
  ///
355
  /// The [onLocaleChanged] callback is called whenever this value changes.
356 357 358 359 360
  ///
  /// See also:
  ///
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this value changes.
361
  List<Locale> get locales => platformDispatcher.locales;
362

363 364 365 366 367 368 369 370 371
  /// Performs the platform-native locale resolution.
  ///
  /// Each platform may return different results.
  ///
  /// If the platform fails to resolve a locale, then this will return null.
  ///
  /// This method returns synchronously and is a direct call to
  /// platform specific APIs without invoking method channels.
  Locale? computePlatformResolvedLocale(List<Locale> supportedLocales) {
372
    return platformDispatcher.computePlatformResolvedLocale(supportedLocales);
373 374
  }

375
  /// A callback that is invoked whenever [locale] changes value.
376
  ///
377
  /// {@macro dart.ui.window.accessorForwardWarning}
378
  ///
Y
Yegor 已提交
379 380 381
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
  ///
382 383 384 385
  /// See also:
  ///
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this callback is invoked.
386
  VoidCallback? get onLocaleChanged => platformDispatcher.onLocaleChanged;
387
  set onLocaleChanged(VoidCallback? callback) {
388
    platformDispatcher.onLocaleChanged = callback;
Y
Yegor 已提交
389
  }
390

391 392
  /// The lifecycle state immediately after dart isolate initialization.
  ///
393
  /// {@macro dart.ui.window.accessorForwardWarning}
394
  ///
395 396 397 398
  /// This property will not be updated as the lifecycle changes.
  ///
  /// It is used to initialize [SchedulerBinding.lifecycleState] at startup
  /// with any buffered lifecycle state events.
399
  String get initialLifecycleState => platformDispatcher.initialLifecycleState;
400

401 402
  /// The system-reported text scale.
  ///
403
  /// {@macro dart.ui.window.accessorForwardWarning}
404
  ///
405 406 407 408 409 410 411 412 413 414
  /// This establishes the text scaling factor to use when rendering text,
  /// according to the user's platform preferences.
  ///
  /// The [onTextScaleFactorChanged] callback is called whenever this value
  /// changes.
  ///
  /// See also:
  ///
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this value changes.
415
  double get textScaleFactor => platformDispatcher.textScaleFactor;
416

417 418
  /// The setting indicating whether time should always be shown in the 24-hour
  /// format.
419
  ///
420
  /// {@macro dart.ui.window.accessorForwardWarning}
421
  ///
422
  /// This option is used by [showTimePicker].
423
  bool get alwaysUse24HourFormat => platformDispatcher.alwaysUse24HourFormat;
424

425 426
  /// A callback that is invoked whenever [textScaleFactor] changes value.
  ///
427
  /// {@macro dart.ui.window.accessorForwardWarning}
428
  ///
429 430 431 432 433 434 435
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
  ///
  /// See also:
  ///
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this callback is invoked.
436
  VoidCallback? get onTextScaleFactorChanged => platformDispatcher.onTextScaleFactorChanged;
437
  set onTextScaleFactorChanged(VoidCallback? callback) {
438
    platformDispatcher.onTextScaleFactorChanged = callback;
439 440
  }

441
  /// The setting indicating the current brightness mode of the host platform.
442
  ///
443
  /// {@macro dart.ui.window.accessorForwardWarning}
444 445 446 447
  ///
  /// If the platform has no preference, [platformBrightness] defaults to
  /// [Brightness.light].
  Brightness get platformBrightness => platformDispatcher.platformBrightness;
448 449 450

  /// A callback that is invoked whenever [platformBrightness] changes value.
  ///
451
  /// {@macro dart.ui.window.accessorForwardWarning}
452
  ///
453 454 455 456 457 458 459
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
  ///
  /// See also:
  ///
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this callback is invoked.
460
  VoidCallback? get onPlatformBrightnessChanged => platformDispatcher.onPlatformBrightnessChanged;
461
  set onPlatformBrightnessChanged(VoidCallback? callback) {
462
    platformDispatcher.onPlatformBrightnessChanged = callback;
463 464
  }

465 466 467 468
  /// A callback that is invoked to notify the window that it is an appropriate
  /// time to provide a scene using the [SceneBuilder] API and the [render]
  /// method.
  ///
469
  /// {@macro dart.ui.window.accessorForwardWarning}
470 471 472 473
  ///
  /// When possible, this is driven by the hardware VSync signal. This is only
  /// called if [scheduleFrame] has been called since the last time this
  /// callback was invoked.
I
Ian Hickson 已提交
474 475 476 477
  ///
  /// The [onDrawFrame] callback is invoked immediately after [onBeginFrame],
  /// after draining any microtasks (e.g. completions of any [Future]s) queued
  /// by the [onBeginFrame] handler.
478
  ///
Y
Yegor 已提交
479 480 481
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
  ///
482 483 484 485 486 487
  /// See also:
  ///
  ///  * [SchedulerBinding], the Flutter framework class which manages the
  ///    scheduling of frames.
  ///  * [RendererBinding], the Flutter framework class which manages layout and
  ///    painting.
488
  FrameCallback? get onBeginFrame => platformDispatcher.onBeginFrame;
489
  set onBeginFrame(FrameCallback? callback) {
490
    platformDispatcher.onBeginFrame = callback;
Y
Yegor 已提交
491
  }
492

I
Ian Hickson 已提交
493
  /// A callback that is invoked for each frame after [onBeginFrame] has
494 495
  /// completed and after the microtask queue has been drained.
  ///
496
  /// {@macro dart.ui.window.accessorForwardWarning}
497 498 499
  ///
  /// This can be used to implement a second phase of frame rendering that
  /// happens after any deferred work queued by the [onBeginFrame] phase.
500
  ///
Y
Yegor 已提交
501 502 503
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
  ///
504 505 506 507 508 509
  /// See also:
  ///
  ///  * [SchedulerBinding], the Flutter framework class which manages the
  ///    scheduling of frames.
  ///  * [RendererBinding], the Flutter framework class which manages layout and
  ///    painting.
510
  VoidCallback? get onDrawFrame => platformDispatcher.onDrawFrame;
511
  set onDrawFrame(VoidCallback? callback) {
512
    platformDispatcher.onDrawFrame = callback;
Y
Yegor 已提交
513
  }
514

515 516 517
  /// A callback that is invoked to report the [FrameTiming] of recently
  /// rasterized frames.
  ///
518
  /// {@macro dart.ui.window.accessorForwardWarning}
519
  ///
520
  /// It's prefered to use [SchedulerBinding.addTimingsCallback] than to use
521
  /// [SingletonFlutterWindow.onReportTimings] directly because
522 523
  /// [SchedulerBinding.addTimingsCallback] allows multiple callbacks.
  ///
524
  /// This can be used to see if the window has missed frames (through
525 526 527 528 529 530 531 532 533 534 535 536 537
  /// [FrameTiming.buildDuration] and [FrameTiming.rasterDuration]), or high
  /// latencies (through [FrameTiming.totalSpan]).
  ///
  /// Unlike [Timeline], the timing information here is available in the release
  /// mode (additional to the profile and the debug mode). Hence this can be
  /// used to monitor the application's performance in the wild.
  ///
  /// {@macro dart.ui.TimingsCallback.list}
  ///
  /// If this is null, no additional work will be done. If this is not null,
  /// Flutter spends less than 0.1ms every 1 second to report the timings
  /// (measured on iPhone6S). The 0.1ms is about 0.6% of 16ms (frame budget for
  /// 60fps), or 0.01% CPU usage per second.
538
  TimingsCallback? get onReportTimings => platformDispatcher.onReportTimings;
539
  set onReportTimings(TimingsCallback? callback) {
540
    platformDispatcher.onReportTimings = callback;
541 542
  }

543
  /// A callback that is invoked when pointer data is available.
544
  ///
545
  /// {@macro dart.ui.window.accessorForwardWarning}
546
  ///
Y
Yegor 已提交
547 548 549
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
  ///
550 551 552 553
  /// See also:
  ///
  ///  * [GestureBinding], the Flutter framework class which manages pointer
  ///    events.
554
  PointerDataPacketCallback? get onPointerDataPacket => platformDispatcher.onPointerDataPacket;
555
  set onPointerDataPacket(PointerDataPacketCallback? callback) {
556
    platformDispatcher.onPointerDataPacket = callback;
Y
Yegor 已提交
557
  }
558

559 560 561
  /// The route or path that the embedder requested when the application was
  /// launched.
  ///
562
  /// {@macro dart.ui.window.accessorForwardWarning}
563
  ///
564 565 566 567
  /// This will be the string "`/`" if no particular route was requested.
  ///
  /// ## Android
  ///
568 569 570 571 572
  /// On Android, the initial route can be set on the [initialRoute](/javadoc/io/flutter/embedding/android/FlutterActivity.NewEngineIntentBuilder.html#initialRoute-java.lang.String-)
  /// method of the [FlutterActivity](/javadoc/io/flutter/embedding/android/FlutterActivity.html)'s
  /// intent builder.
  ///
  /// On a standalone engine, see https://flutter.dev/docs/development/add-to-app/android/add-flutter-screen#initial-route-with-a-cached-engine.
573 574 575
  ///
  /// ## iOS
  ///
576 577 578 579 580
  /// On iOS, the initial route can be set on the `initialRoute`
  /// parameter of the [FlutterViewController](/objcdoc/Classes/FlutterViewController.html)'s
  /// initializer.
  ///
  /// On a standalone engine, see https://flutter.dev/docs/development/add-to-app/ios/add-flutter-screen#route.
581 582 583 584 585 586
  ///
  /// See also:
  ///
  ///  * [Navigator], a widget that handles routing.
  ///  * [SystemChannels.navigation], which handles subsequent navigation
  ///    requests from the embedder.
587 588 589 590 591
  String get defaultRouteName => platformDispatcher.defaultRouteName;

  /// Requests that, at the next appropriate opportunity, the [onBeginFrame] and
  /// [onDrawFrame] callbacks be invoked.
  ///
592
  /// {@template dart.ui.window.functionForwardWarning}
593 594 595 596 597 598 599
  /// Calling this function forwards the call to the same function on the
  /// [PlatformDispatcher] singleton, so instead of calling it here, you should
  /// consider calling it on `WidgetsBinding.instance.platformDispatcher` instead (or, when
  /// `WidgetsBinding` isn't available, on [PlatformDispatcher.instance]). The
  /// reason this function forwards to the [PlatformDispatcher] is to provide
  /// convenience for applications that only use a single main window.
  /// {@endtemplate}
600 601 602
  ///
  /// See also:
  ///
603 604 605
  /// * [SchedulerBinding], the Flutter framework class which manages the
  ///   scheduling of frames.
  void scheduleFrame() => platformDispatcher.scheduleFrame();
606 607 608 609

  /// Whether the user has requested that [updateSemantics] be called when
  /// the semantic contents of window changes.
  ///
610
  /// {@macro dart.ui.window.accessorForwardWarning}
611
  ///
612 613
  /// The [onSemanticsEnabledChanged] callback is called whenever this value
  /// changes.
614
  bool get semanticsEnabled => platformDispatcher.semanticsEnabled;
615 616

  /// A callback that is invoked when the value of [semanticsEnabled] changes.
Y
Yegor 已提交
617
  ///
618
  /// {@macro dart.ui.window.accessorForwardWarning}
619
  ///
Y
Yegor 已提交
620 621
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
622
  VoidCallback? get onSemanticsEnabledChanged => platformDispatcher.onSemanticsEnabledChanged;
623
  set onSemanticsEnabledChanged(VoidCallback? callback) {
624
    platformDispatcher.onSemanticsEnabledChanged = callback;
Y
Yegor 已提交
625
  }
626 627 628 629

  /// A callback that is invoked whenever the user requests an action to be
  /// performed.
  ///
630
  /// {@macro dart.ui.window.accessorForwardWarning}
631
  ///
632 633
  /// This callback is used when the user expresses the action they wish to
  /// perform based on the semantics supplied by [updateSemantics].
Y
Yegor 已提交
634 635 636
  ///
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
637
  SemanticsActionCallback? get onSemanticsAction => platformDispatcher.onSemanticsAction;
638
  set onSemanticsAction(SemanticsActionCallback? callback) {
639
    platformDispatcher.onSemanticsAction = callback;
Y
Yegor 已提交
640
  }
641

642
  /// Additional accessibility features that may be enabled by the platform.
643
  AccessibilityFeatures get accessibilityFeatures => platformDispatcher.accessibilityFeatures;
644

645
  /// A callback that is invoked when the value of [accessibilityFeatures] changes.
646
  ///
647
  /// {@macro dart.ui.window.accessorForwardWarning}
648
  ///
649 650
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
651
  VoidCallback? get onAccessibilityFeaturesChanged => platformDispatcher.onAccessibilityFeaturesChanged;
652
  set onAccessibilityFeaturesChanged(VoidCallback? callback) {
653
    platformDispatcher.onAccessibilityFeaturesChanged = callback;
654 655
  }

656 657
  /// Change the retained semantics data about this window.
  ///
658
  /// {@macro dart.ui.window.functionForwardWarning}
659
  ///
C
Chris Bracken 已提交
660
  /// If [semanticsEnabled] is true, the user has requested that this function
661 662 663 664
  /// be called whenever the semantic content of this window changes.
  ///
  /// In either case, this function disposes the given update, which means the
  /// semantics update cannot be used further.
665
  void updateSemantics(SemanticsUpdate update) => platformDispatcher.updateSemantics(update);
666 667

  /// Sends a message to a platform-specific plugin.
668
  ///
669
  /// {@macro dart.ui.window.functionForwardWarning}
670
  ///
A
Adam Barth 已提交
671 672 673 674
  /// The `name` parameter determines which plugin receives the message. The
  /// `data` parameter contains the message payload and is typically UTF-8
  /// encoded JSON but can be arbitrary data. If the plugin replies to the
  /// message, `callback` will be called with the response.
Y
Yegor 已提交
675 676 677
  ///
  /// The framework invokes [callback] in the same zone in which this method
  /// was called.
678
  void sendPlatformMessage(String name,
679 680 681
      ByteData? data,
      PlatformMessageResponseCallback? callback) {
    platformDispatcher.sendPlatformMessage(name, data, callback);
682 683
  }

A
Adam Barth 已提交
684 685 686
  /// Called whenever this window receives a message from a platform-specific
  /// plugin.
  ///
687
  /// {@macro dart.ui.window.accessorForwardWarning}
688
  ///
A
Adam Barth 已提交
689 690 691 692 693
  /// The `name` parameter determines which plugin sent the message. The `data`
  /// parameter is the payload and is typically UTF-8 encoded JSON but can be
  /// arbitrary data.
  ///
  /// Message handlers must call the function given in the `callback` parameter.
694
  /// If the handler does not need to respond, the handler should pass null to
A
Adam Barth 已提交
695
  /// the callback.
Y
Yegor 已提交
696 697 698
  ///
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
699
  // TODO(ianh): deprecate once framework uses [ChannelBuffers.setListener].
700
  PlatformMessageCallback? get onPlatformMessage => platformDispatcher.onPlatformMessage;
701
  set onPlatformMessage(PlatformMessageCallback? callback) {
702
    platformDispatcher.onPlatformMessage = callback;
Y
Yegor 已提交
703
  }
704

705 706 707
  /// Set the debug name associated with this platform dispatcher's root
  /// isolate.
  ///
708
  /// {@macro dart.ui.window.accessorForwardWarning}
709
  ///
710 711
  /// Normally debug names are automatically generated from the Dart port, entry
  /// point, and source file. For example: `main.dart$main-1234`.
712
  ///
713 714 715 716
  /// This can be combined with flutter tools `--isolate-filter` flag to debug
  /// specific root isolates. For example: `flutter attach --isolate-filter=[name]`.
  /// Note that this does not rename any child isolates of the root.
  void setIsolateDebugName(String name) => PlatformDispatcher.instance.setIsolateDebugName(name);
A
Adam Barth 已提交
717 718
}

719 720 721 722 723
/// Additional accessibility features that may be enabled by the platform.
///
/// It is not possible to enable these settings from Flutter, instead they are
/// used by the platform to indicate that additional accessibility features are
/// enabled.
724 725 726
//
// When changes are made to this class, the equivalent APIs in each of the
// embedders *must* be updated.
727 728 729 730 731 732
class AccessibilityFeatures {
  const AccessibilityFeatures._(this._index);

  static const int _kAccessibleNavigation = 1 << 0;
  static const int _kInvertColorsIndex = 1 << 1;
  static const int _kDisableAnimationsIndex = 1 << 2;
733
  static const int _kBoldTextIndex = 1 << 3;
734
  static const int _kReduceMotionIndex = 1 << 4;
735
  static const int _kHighContrastIndex = 1 << 5;
736 737

  // A bitfield which represents each enabled feature.
738
  final int _index;
739 740 741 742 743

  /// Whether there is a running accessibility service which is changing the
  /// interaction model of the device.
  ///
  /// For example, TalkBack on Android and VoiceOver on iOS enable this flag.
744
  bool get accessibleNavigation => _kAccessibleNavigation & _index != 0;
745 746

  /// The platform is inverting the colors of the application.
747
  bool get invertColors => _kInvertColorsIndex & _index != 0;
748 749

  /// The platform is requesting that animations be disabled or simplified.
750
  bool get disableAnimations => _kDisableAnimationsIndex & _index != 0;
751

752 753 754
  /// The platform is requesting that text be rendered at a bold font weight.
  ///
  /// Only supported on iOS.
755
  bool get boldText => _kBoldTextIndex & _index != 0;
756

757 758 759 760
  /// The platform is requesting that certain animations be simplified and
  /// parallax effects removed.
  ///
  /// Only supported on iOS.
761
  bool get reduceMotion => _kReduceMotionIndex & _index != 0;
762

763 764 765
  /// The platform is requesting that UI be rendered with darker colors.
  ///
  /// Only supported on iOS.
766
  bool get highContrast => _kHighContrastIndex & _index != 0;
767

768
  @override
769
  String toString() {
770 771 772 773 774 775 776
    final List<String> features = <String>[];
    if (accessibleNavigation)
      features.add('accessibleNavigation');
    if (invertColors)
      features.add('invertColors');
    if (disableAnimations)
      features.add('disableAnimations');
777 778
    if (boldText)
      features.add('boldText');
779 780
    if (reduceMotion)
      features.add('reduceMotion');
781 782
    if (highContrast)
      features.add('highContrast');
783 784 785 786
    return 'AccessibilityFeatures$features';
  }

  @override
A
Alexandre Ardhuin 已提交
787
  bool operator ==(Object other) {
788 789
    if (other.runtimeType != runtimeType)
      return false;
790 791
    return other is AccessibilityFeatures
        && other._index == _index;
792 793 794
  }

  @override
795
  int get hashCode => _index.hashCode;
796 797
}

798 799 800 801 802 803 804 805 806 807 808 809 810 811 812
/// Describes the contrast of a theme or color palette.
enum Brightness {
  /// The color is dark and will require a light text color to achieve readable
  /// contrast.
  ///
  /// For example, the color might be dark grey, requiring white text.
  dark,

  /// The color is light and will require a dark text color to achieve readable
  /// contrast.
  ///
  /// For example, the color might be bright white, requiring black text.
  light,
}

813 814 815 816 817 818
/// The [SingletonFlutterWindow] representing the main window for applications
/// where there is only one window, such as applications designed for
/// single-display mobile devices.
///
/// Applications that are designed to use more than one window should interact
/// with the `WidgetsBinding.instance.platformDispatcher` instead.
L
liyuqian 已提交
819
///
820 821 822
/// Consider avoiding static references to this singleton through
/// [PlatformDispatcher.instance] and instead prefer using a binding for
/// dependency resolution such as `WidgetsBinding.instance.window`.
823
///
824
/// Static access of this `window` object means that Flutter has few, if any
L
liyuqian 已提交
825 826 827 828 829 830 831
/// options to fake or mock the given object in tests. Even in cases where Dart
/// offers special language constructs to forcefully shadow such properties,
/// those mechanisms would only be reasonable for tests and they would not be
/// reasonable for a future of Flutter where we legitimately want to select an
/// appropriate implementation at runtime.
///
/// The only place that `WidgetsBinding.instance.window` is inappropriate is if
832 833 834 835 836 837 838 839 840 841
/// access to these APIs is required before the binding is initialized by
/// invoking `runApp()` or `WidgetsFlutterBinding.instance.ensureInitialized()`.
/// In that case, it is necessary (though unfortunate) to use the
/// [PlatformDispatcher.instance] object statically.
///
/// See also:
///
/// * [PlatformDispatcher.views], contains the current list of Flutter windows
///   belonging to the application, including top level application windows like
///   this one.
842
final SingletonFlutterWindow window = SingletonFlutterWindow._(0, PlatformDispatcher.instance);