migrate scheduler to nullsafety (#61570)

diff --git a/packages/flutter/lib/scheduler.dart b/packages/flutter/lib/scheduler.dart
index 2652ea3..f1cbdc2 100644
--- a/packages/flutter/lib/scheduler.dart
+++ b/packages/flutter/lib/scheduler.dart
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// @dart = 2.8
-
 /// The Flutter Scheduler library.
 ///
 /// To use, import `package:flutter/scheduler.dart`.
diff --git a/packages/flutter/lib/src/scheduler/binding.dart b/packages/flutter/lib/src/scheduler/binding.dart
index cbcbbdc..0d7ec55 100644
--- a/packages/flutter/lib/src/scheduler/binding.dart
+++ b/packages/flutter/lib/src/scheduler/binding.dart
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// @dart = 2.8
-
 import 'dart:async';
 import 'dart:collection';
 import 'dart:developer' show Flow, Timeline;
@@ -57,7 +55,7 @@
 /// See also:
 ///
 ///  * [defaultSchedulingStrategy], the default [SchedulingStrategy] for [SchedulerBinding.schedulingStrategy].
-typedef SchedulingStrategy = bool Function({ int priority, SchedulerBinding scheduler });
+typedef SchedulingStrategy = bool Function({ required int priority, required SchedulerBinding scheduler });
 
 class _TaskEntry<T> {
   _TaskEntry(this.task, this.priority, this.debugLabel, this.flow) {
@@ -65,15 +63,14 @@
       debugStack = StackTrace.current;
       return true;
     }());
-    completer = Completer<T>();
   }
   final TaskCallback<T> task;
   final int priority;
-  final String debugLabel;
-  final Flow flow;
+  final String? debugLabel;
+  final Flow? flow;
 
-  StackTrace debugStack;
-  Completer<T> completer;
+  late StackTrace debugStack;
+  final Completer<T> completer = Completer<T>();
 
   void run() {
     if (!kReleaseMode) {
@@ -82,7 +79,7 @@
         () {
           completer.complete(task());
         },
-        flow: flow != null ? Flow.step(flow.id) : null,
+        flow: flow != null ? Flow.step(flow!.id) : null,
       );
     } else {
       completer.complete(task());
@@ -123,8 +120,8 @@
 
   final FrameCallback callback;
 
-  static StackTrace debugCurrentCallbackStack;
-  StackTrace debugStack;
+  static StackTrace? debugCurrentCallbackStack;
+  StackTrace? debugStack;
 }
 
 /// The various phases that a [SchedulerBinding] goes through during
@@ -292,7 +289,7 @@
           callback(timings);
         }
       } catch (exception, stack) {
-        InformationCollector collector;
+        InformationCollector? collector;
         assert(() {
           collector = () sync* {
             yield DiagnosticsProperty<TimingsCallback>(
@@ -314,8 +311,8 @@
   }
 
   /// The current [SchedulerBinding], if one has been created.
-  static SchedulerBinding get instance => _instance;
-  static SchedulerBinding _instance;
+  static SchedulerBinding? get instance => _instance;
+  static SchedulerBinding? _instance;
 
   @override
   void initServiceExtensions() {
@@ -340,8 +337,8 @@
   ///
   /// The preferred way to watch for changes to this value is using
   /// [WidgetsBindingObserver.didChangeAppLifecycleState].
-  AppLifecycleState get lifecycleState => _lifecycleState;
-  AppLifecycleState _lifecycleState;
+  AppLifecycleState? get lifecycleState => _lifecycleState;
+  AppLifecycleState? _lifecycleState;
 
   /// Called when the application lifecycle state changes.
   ///
@@ -398,8 +395,8 @@
   Future<T> scheduleTask<T>(
     TaskCallback<T> task,
     Priority priority, {
-    String debugLabel,
-    Flow flow,
+    String? debugLabel,
+    Flow? flow,
   }) {
     final bool isFirstTask = _taskQueue.isEmpty;
     final _TaskEntry<T> entry = _TaskEntry<T>(
@@ -462,7 +459,7 @@
         _taskQueue.removeFirst();
         entry.run();
       } catch (exception, exceptionStack) {
-        StackTrace callbackStack;
+        StackTrace? callbackStack;
         assert(() {
           callbackStack = entry.debugStack;
           return true;
@@ -585,7 +582,7 @@
               );
             }
             for (final int id in callbacks.keys) {
-              final _FrameCallbackEntry entry = callbacks[id];
+              final _FrameCallbackEntry entry = callbacks[id]!;
               yield DiagnosticsStackTrace('── callback $id ──', entry.debugStack, showSeparator: false);
             }
           },
@@ -622,7 +619,7 @@
         debugPrint(
           FlutterError.defaultStackFilter(
             FlutterError.demangleStackTrace(
-              _FrameCallbackEntry.debugCurrentCallbackStack,
+              _FrameCallbackEntry.debugCurrentCallbackStack!,
             ).toString().trimRight().split('\n')
           ).join('\n')
         );
@@ -677,7 +674,7 @@
     _postFrameCallbacks.add(callback);
   }
 
-  Completer<void> _nextFrameCompleter;
+  Completer<void>? _nextFrameCompleter;
 
   /// Returns a Future that completes after the frame completes.
   ///
@@ -694,11 +691,11 @@
         scheduleFrame();
       _nextFrameCompleter = Completer<void>();
       addPostFrameCallback((Duration timeStamp) {
-        _nextFrameCompleter.complete();
+        _nextFrameCompleter!.complete();
         _nextFrameCompleter = null;
       });
     }
-    return _nextFrameCompleter.future;
+    return _nextFrameCompleter!.future;
   }
 
   /// Whether this scheduler has requested that [handleBeginFrame] be called soon.
@@ -885,7 +882,7 @@
     });
   }
 
-  Duration _firstRawTimeStampInEpoch;
+  Duration? _firstRawTimeStampInEpoch;
   Duration _epochStart = Duration.zero;
   Duration _lastRawTimeStamp = Duration.zero;
 
@@ -920,7 +917,7 @@
   /// These mechanisms together combine to ensure that the durations we give
   /// during frame callbacks are monotonically increasing.
   Duration _adjustForEpoch(Duration rawTimeStamp) {
-    final Duration rawDurationSinceEpoch = _firstRawTimeStampInEpoch == null ? Duration.zero : rawTimeStamp - _firstRawTimeStampInEpoch;
+    final Duration rawDurationSinceEpoch = _firstRawTimeStampInEpoch == null ? Duration.zero : rawTimeStamp - _firstRawTimeStampInEpoch!;
     return Duration(microseconds: (rawDurationSinceEpoch.inMicroseconds / timeDilation).round() + _epochStart.inMicroseconds);
   }
 
@@ -931,9 +928,9 @@
   /// produced.
   Duration get currentFrameTimeStamp {
     assert(_currentFrameTimeStamp != null);
-    return _currentFrameTimeStamp;
+    return _currentFrameTimeStamp!;
   }
-  Duration _currentFrameTimeStamp;
+  Duration? _currentFrameTimeStamp;
 
   /// The raw time stamp as provided by the engine to [Window.onBeginFrame]
   /// for the frame currently being processed.
@@ -952,7 +949,7 @@
   }
 
   int _debugFrameNumber = 0;
-  String _debugBanner;
+  String? _debugBanner;
   bool _ignoreNextEngineDrawFrame = false;
 
   void _handleBeginFrame(Duration rawTimeStamp) {
@@ -995,7 +992,7 @@
   /// [debugPrintEndFrameBanner] to true. This allows you to distinguish log
   /// statements printed during a frame from those printed between frames (e.g.
   /// in response to events or timers).
-  void handleBeginFrame(Duration rawTimeStamp) {
+  void handleBeginFrame(Duration? rawTimeStamp) {
     Timeline.startSync('Frame', arguments: timelineArgumentsIndicatingLandmarkEvent);
     _firstRawTimeStampInEpoch ??= rawTimeStamp;
     _currentFrameTimeStamp = _adjustForEpoch(rawTimeStamp ?? _lastRawTimeStamp);
@@ -1008,7 +1005,7 @@
       if (debugPrintBeginFrameBanner || debugPrintEndFrameBanner) {
         final StringBuffer frameTimeStampDescription = StringBuffer();
         if (rawTimeStamp != null) {
-          _debugDescribeTimeStamp(_currentFrameTimeStamp, frameTimeStampDescription);
+          _debugDescribeTimeStamp(_currentFrameTimeStamp!, frameTimeStampDescription);
         } else {
           frameTimeStampDescription.write('(warm-up frame)');
         }
@@ -1029,7 +1026,7 @@
       _transientCallbacks = <int, _FrameCallbackEntry>{};
       callbacks.forEach((int id, _FrameCallbackEntry callbackEntry) {
         if (!_removedIds.contains(id))
-          _invokeFrameCallback(callbackEntry.callback, _currentFrameTimeStamp, callbackEntry.debugStack);
+          _invokeFrameCallback(callbackEntry.callback, _currentFrameTimeStamp!, callbackEntry.debugStack);
       });
       _removedIds.clear();
     } finally {
@@ -1053,7 +1050,7 @@
       // PERSISTENT FRAME CALLBACKS
       _schedulerPhase = SchedulerPhase.persistentCallbacks;
       for (final FrameCallback callback in _persistentCallbacks)
-        _invokeFrameCallback(callback, _currentFrameTimeStamp);
+        _invokeFrameCallback(callback, _currentFrameTimeStamp!);
 
       // POST-FRAME CALLBACKS
       _schedulerPhase = SchedulerPhase.postFrameCallbacks;
@@ -1061,13 +1058,13 @@
           List<FrameCallback>.from(_postFrameCallbacks);
       _postFrameCallbacks.clear();
       for (final FrameCallback callback in localPostFrameCallbacks)
-        _invokeFrameCallback(callback, _currentFrameTimeStamp);
+        _invokeFrameCallback(callback, _currentFrameTimeStamp!);
     } finally {
       _schedulerPhase = SchedulerPhase.idle;
       Timeline.finishSync(); // end the Frame
       assert(() {
         if (debugPrintEndFrameBanner)
-          debugPrint('▀' * _debugBanner.length);
+          debugPrint('▀' * _debugBanner!.length);
         _debugBanner = null;
         return true;
       }());
@@ -1106,7 +1103,7 @@
   // Wraps the callback in a try/catch and forwards any error to
   // [debugSchedulerExceptionHandler], if set. If not set, then simply prints
   // the error.
-  void _invokeFrameCallback(FrameCallback callback, Duration timeStamp, [ StackTrace callbackStack ]) {
+  void _invokeFrameCallback(FrameCallback callback, Duration timeStamp, [ StackTrace? callbackStack ]) {
     assert(callback != null);
     assert(_FrameCallbackEntry.debugCurrentCallbackStack == null);
     assert(() {
@@ -1143,7 +1140,7 @@
 /// If there are any frame callbacks registered, only runs tasks with
 /// a [Priority] of [Priority.animation] or higher. Otherwise, runs
 /// all tasks.
-bool defaultSchedulingStrategy({ int priority, SchedulerBinding scheduler }) {
+bool defaultSchedulingStrategy({ required int priority, required SchedulerBinding scheduler }) {
   if (scheduler.transientCallbackCount > 0)
     return priority >= Priority.animation.value;
   return true;
diff --git a/packages/flutter/lib/src/scheduler/debug.dart b/packages/flutter/lib/src/scheduler/debug.dart
index dc21d03..82af69f 100644
--- a/packages/flutter/lib/src/scheduler/debug.dart
+++ b/packages/flutter/lib/src/scheduler/debug.dart
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// @dart = 2.8
-
 import 'package:flutter/foundation.dart';
 
 // Any changes to this file should be reflected in the debugAssertAllSchedulerVarsUnset()
diff --git a/packages/flutter/lib/src/scheduler/priority.dart b/packages/flutter/lib/src/scheduler/priority.dart
index 8b108d6..12cecc9 100644
--- a/packages/flutter/lib/src/scheduler/priority.dart
+++ b/packages/flutter/lib/src/scheduler/priority.dart
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// @dart = 2.8
-
 import 'package:flutter/foundation.dart';
 
 /// A task priority, as passed to [SchedulerBinding.scheduleTask].
diff --git a/packages/flutter/lib/src/scheduler/ticker.dart b/packages/flutter/lib/src/scheduler/ticker.dart
index 0c02f4f..1842401 100644
--- a/packages/flutter/lib/src/scheduler/ticker.dart
+++ b/packages/flutter/lib/src/scheduler/ticker.dart
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// @dart = 2.8
-
 import 'dart:async';
 
 import 'package:flutter/foundation.dart';
@@ -71,7 +69,7 @@
     }());
   }
 
-  TickerFuture _future;
+  TickerFuture? _future;
 
   /// Whether this ticker has been silenced.
   ///
@@ -115,9 +113,9 @@
       return false;
     if (muted)
       return false;
-    if (SchedulerBinding.instance.framesEnabled)
+    if (SchedulerBinding.instance!.framesEnabled)
       return true;
-    if (SchedulerBinding.instance.schedulerPhase != SchedulerPhase.idle)
+    if (SchedulerBinding.instance!.schedulerPhase != SchedulerPhase.idle)
       return true; // for example, we might be in a warm-up frame or forced frame
     return false;
   }
@@ -130,7 +128,7 @@
   /// [isTicking].
   bool get isActive => _future != null;
 
-  Duration _startTime;
+  Duration? _startTime;
 
   /// Starts the clock for this [Ticker]. If the ticker is not [muted], then this
   /// also starts calling the ticker's callback once per animation frame.
@@ -163,10 +161,10 @@
     if (shouldScheduleTick) {
       scheduleTick();
     }
-    if (SchedulerBinding.instance.schedulerPhase.index > SchedulerPhase.idle.index &&
-        SchedulerBinding.instance.schedulerPhase.index < SchedulerPhase.postFrameCallbacks.index)
-      _startTime = SchedulerBinding.instance.currentFrameTimeStamp;
-    return _future;
+    if (SchedulerBinding.instance!.schedulerPhase.index > SchedulerPhase.idle.index &&
+        SchedulerBinding.instance!.schedulerPhase.index < SchedulerPhase.postFrameCallbacks.index)
+      _startTime = SchedulerBinding.instance!.currentFrameTimeStamp;
+    return _future!;
   }
 
   /// Adds a debug representation of a [Ticker] optimized for including in error
@@ -197,7 +195,7 @@
     // We take the _future into a local variable so that isTicking is false
     // when we actually complete the future (isTicking uses _future to
     // determine its state).
-    final TickerFuture localFuture = _future;
+    final TickerFuture localFuture = _future!;
     _future = null;
     _startTime = null;
     assert(!isActive);
@@ -213,7 +211,7 @@
 
   final TickerCallback _onTick;
 
-  int _animationId;
+  int? _animationId;
 
   /// Whether this [Ticker] has already scheduled a frame callback.
   @protected
@@ -237,7 +235,7 @@
     _animationId = null;
 
     _startTime ??= timeStamp;
-    _onTick(timeStamp - _startTime);
+    _onTick(timeStamp - _startTime!);
 
     // The onTick callback may have scheduled another tick already, for
     // example by calling stop then start again.
@@ -252,7 +250,7 @@
   void scheduleTick({ bool rescheduling = false }) {
     assert(!scheduled);
     assert(shouldScheduleTick);
-    _animationId = SchedulerBinding.instance.scheduleFrameCallback(_tick, rescheduling: rescheduling);
+    _animationId = SchedulerBinding.instance!.scheduleFrameCallback(_tick, rescheduling: rescheduling);
   }
 
   /// Cancels the frame callback that was requested by [scheduleTick], if any.
@@ -264,7 +262,7 @@
   @protected
   void unscheduleTick() {
     if (scheduled) {
-      SchedulerBinding.instance.cancelFrameCallbackWithId(_animationId);
+      SchedulerBinding.instance!.cancelFrameCallbackWithId(_animationId!);
       _animationId = null;
     }
     assert(!shouldScheduleTick);
@@ -301,7 +299,7 @@
   @mustCallSuper
   void dispose() {
     if (_future != null) {
-      final TickerFuture localFuture = _future;
+      final TickerFuture localFuture = _future!;
       _future = null;
       assert(!isActive);
       unscheduleTick();
@@ -319,8 +317,8 @@
   /// An optional label can be provided for debugging purposes.
   ///
   /// This label will appear in the [toString] output in debug builds.
-  final String debugLabel;
-  StackTrace _debugCreationStack;
+  final String? debugLabel;
+  late StackTrace _debugCreationStack;
 
   @override
   String toString({ bool debugIncludeStack = false }) {
@@ -374,14 +372,14 @@
   }
 
   final Completer<void> _primaryCompleter = Completer<void>();
-  Completer<void> _secondaryCompleter;
-  bool _completed; // null means unresolved, true means complete, false means canceled
+  Completer<void>? _secondaryCompleter;
+  bool? _completed; // null means unresolved, true means complete, false means canceled
 
   void _complete() {
     assert(_completed == null);
     _completed = true;
-    _primaryCompleter.complete(null);
-    _secondaryCompleter?.complete(null);
+    _primaryCompleter.complete();
+    _secondaryCompleter?.complete();
   }
 
   void _cancel(Ticker ticker) {
@@ -415,14 +413,14 @@
     if (_secondaryCompleter == null) {
       _secondaryCompleter = Completer<void>();
       if (_completed != null) {
-        if (_completed) {
-          _secondaryCompleter.complete();
+        if (_completed!) {
+          _secondaryCompleter!.complete();
         } else {
-          _secondaryCompleter.completeError(const TickerCanceled());
+          _secondaryCompleter!.completeError(const TickerCanceled());
         }
       }
     }
-    return _secondaryCompleter.future;
+    return _secondaryCompleter!.future;
   }
 
   @override
@@ -431,17 +429,17 @@
   }
 
   @override
-  Future<void> catchError(Function onError, { bool test(dynamic error) }) {
+  Future<void> catchError(Function onError, { bool Function(Object)? test }) {
     return _primaryCompleter.future.catchError(onError, test: test);
   }
 
   @override
-  Future<R> then<R>(FutureOr<R> onValue(void value), { Function onError }) {
+  Future<R> then<R>(FutureOr<R> onValue(void value), { Function? onError }) {
     return _primaryCompleter.future.then<R>(onValue, onError: onError);
   }
 
   @override
-  Future<void> timeout(Duration timeLimit, { dynamic onTimeout() }) {
+  Future<void> timeout(Duration timeLimit, { FutureOr<void> Function()? onTimeout }) {
     return _primaryCompleter.future.timeout(timeLimit, onTimeout: onTimeout);
   }
 
@@ -451,7 +449,7 @@
   }
 
   @override
-  String toString() => '${describeIdentity(this)}(${ _completed == null ? "active" : _completed ? "complete" : "canceled" })';
+  String toString() => '${describeIdentity(this)}(${ _completed == null ? "active" : _completed! ? "complete" : "canceled" })';
 }
 
 /// Exception thrown by [Ticker] objects on the [TickerFuture.orCancel] future
@@ -464,7 +462,7 @@
   ///
   /// This may be null in the case that the [Future] created for
   /// [TickerFuture.orCancel] was created after the ticker was canceled.
-  final Ticker ticker;
+  final Ticker? ticker;
 
   @override
   String toString() {