Reland https://github.com/flutter/flutter/pull/33663 (#33828)
diff --git a/packages/flutter/lib/foundation.dart b/packages/flutter/lib/foundation.dart index f2e6791..725efc2 100644 --- a/packages/flutter/lib/foundation.dart +++ b/packages/flutter/lib/foundation.dart
@@ -35,6 +35,7 @@ export 'src/foundation/assertions.dart'; export 'src/foundation/basic_types.dart'; export 'src/foundation/binding.dart'; +export 'src/foundation/bitfield.dart'; export 'src/foundation/change_notifier.dart'; export 'src/foundation/collections.dart'; export 'src/foundation/consolidate_response.dart';
diff --git a/packages/flutter/lib/src/animation/animation.dart b/packages/flutter/lib/src/animation/animation.dart index 8522785..3a6bd0a 100644 --- a/packages/flutter/lib/src/animation/animation.dart +++ b/packages/flutter/lib/src/animation/animation.dart
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' show VoidCallback; import 'package:flutter/foundation.dart';
diff --git a/packages/flutter/lib/src/animation/animations.dart b/packages/flutter/lib/src/animation/animations.dart index 80cc60e..4f0dc26 100644 --- a/packages/flutter/lib/src/animation/animations.dart +++ b/packages/flutter/lib/src/animation/animations.dart
@@ -3,7 +3,6 @@ // found in the LICENSE file. import 'dart:math' as math; -import 'dart:ui' show VoidCallback; import 'package:flutter/foundation.dart';
diff --git a/packages/flutter/lib/src/animation/listener_helpers.dart b/packages/flutter/lib/src/animation/listener_helpers.dart index 2236ac5..d2f8785 100644 --- a/packages/flutter/lib/src/animation/listener_helpers.dart +++ b/packages/flutter/lib/src/animation/listener_helpers.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. -import 'dart:ui' show VoidCallback; - import 'package:flutter/foundation.dart'; import 'animation.dart';
diff --git a/packages/flutter/lib/src/foundation/_bitfield_io.dart b/packages/flutter/lib/src/foundation/_bitfield_io.dart new file mode 100644 index 0000000..f1205e5 --- /dev/null +++ b/packages/flutter/lib/src/foundation/_bitfield_io.dart
@@ -0,0 +1,48 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'bitfield.dart' as bitfield; + +/// The dart:io implementation of [bitfield.kMaxUnsignedSMI]. +const int kMaxUnsignedSMI = 0x3FFFFFFFFFFFFFFF; + +/// The dart:io implementation of [bitfield.Bitfield]. +class BitField<T extends dynamic> implements bitfield.BitField<T> { + /// The dart:io implementation of [bitfield.Bitfield()]. + BitField(this._length) + : assert(_length <= _smiBits), + _bits = _allZeros; + + /// The dart:io implementation of [bitfield.Bitfield.filled]. + BitField.filled(this._length, bool value) + : assert(_length <= _smiBits), + _bits = value ? _allOnes : _allZeros; + + final int _length; + int _bits; + + static const int _smiBits = 62; // see https://www.dartlang.org/articles/numeric-computation/#smis-and-mints + static const int _allZeros = 0; + static const int _allOnes = kMaxUnsignedSMI; // 2^(_kSMIBits+1)-1 + + @override + bool operator [](T index) { + assert(index.index < _length); + return (_bits & 1 << index.index) > 0; + } + + @override + void operator []=(T index, bool value) { + assert(index.index < _length); + if (value) + _bits = _bits | (1 << index.index); + else + _bits = _bits & ~(1 << index.index); + } + + @override + void reset([ bool value = false ]) { + _bits = value ? _allOnes : _allZeros; + } +}
diff --git a/packages/flutter/lib/src/foundation/bitfield_unsupported.dart b/packages/flutter/lib/src/foundation/_bitfield_web.dart similarity index 60% rename from packages/flutter/lib/src/foundation/bitfield_unsupported.dart rename to packages/flutter/lib/src/foundation/_bitfield_web.dart index c7baf47..2fa843a 100644 --- a/packages/flutter/lib/src/foundation/bitfield_unsupported.dart +++ b/packages/flutter/lib/src/foundation/_bitfield_web.dart
@@ -2,32 +2,34 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/// Unsupported. +import 'bitfield.dart' as bitfield; + +/// The dart:html implementation of [bitfield.kMaxUnsignedSMI]. const int kMaxUnsignedSMI = 0; -/// Unsupported. -class BitField<T extends dynamic> { - /// Unsupported. - // Ignored so that both bitfield implementations have the same API. +/// The dart:html implementation of [bitfield.Bitfield]. +class BitField<T extends dynamic> implements bitfield.BitField<T> { + /// The dart:html implementation of [bitfield.Bitfield]. + // Can remove when we have metaclasses. // ignore: avoid_unused_constructor_parameters BitField(int length); - /// Unsupported. - // Ignored so that both bitfield implementations have the same API. + /// The dart:html implementation of [bitfield.Bitfield.filled]. + // Can remove when we have metaclasses. // ignore: avoid_unused_constructor_parameters BitField.filled(int length, bool value); - /// Unsupported. + @override bool operator [](T index) { throw UnsupportedError('Not supported when compiling to JavaScript'); } - /// Unsupported. + @override void operator []=(T index, bool value) { throw UnsupportedError('Not supported when compiling to JavaScript'); } - /// Unsupported. + @override void reset([ bool value = false ]) { throw UnsupportedError('Not supported when compiling to JavaScript'); }
diff --git a/packages/flutter/lib/src/foundation/_isolates_io.dart b/packages/flutter/lib/src/foundation/_isolates_io.dart new file mode 100644 index 0000000..be2a418 --- /dev/null +++ b/packages/flutter/lib/src/foundation/_isolates_io.dart
@@ -0,0 +1,92 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; +import 'dart:developer'; +import 'dart:isolate'; +import 'package:meta/meta.dart'; + +import 'constants.dart'; +import 'isolates.dart' as isolates; + +/// The dart:io implementation of [isolate.compute]. +Future<R> compute<Q, R>(isolates.ComputeCallback<Q, R> callback, Q message, { String debugLabel }) async { + if (!kReleaseMode) { + debugLabel ??= callback.toString(); + } + final Flow flow = Flow.begin(); + Timeline.startSync('$debugLabel: start', flow: flow); + final ReceivePort resultPort = ReceivePort(); + final ReceivePort errorPort = ReceivePort(); + Timeline.finishSync(); + final Isolate isolate = await Isolate.spawn<_IsolateConfiguration<Q, FutureOr<R>>>( + _spawn, + _IsolateConfiguration<Q, FutureOr<R>>( + callback, + message, + resultPort.sendPort, + debugLabel, + flow.id, + ), + errorsAreFatal: true, + onExit: resultPort.sendPort, + onError: errorPort.sendPort, + ); + final Completer<R> result = Completer<R>(); + errorPort.listen((dynamic errorData) { + assert(errorData is List<dynamic>); + assert(errorData.length == 2); + final Exception exception = Exception(errorData[0]); + final StackTrace stack = StackTrace.fromString(errorData[1]); + if (result.isCompleted) { + Zone.current.handleUncaughtError(exception, stack); + } else { + result.completeError(exception, stack); + } + }); + resultPort.listen((dynamic resultData) { + assert(resultData == null || resultData is R); + if (!result.isCompleted) + result.complete(resultData); + }); + await result.future; + Timeline.startSync('$debugLabel: end', flow: Flow.end(flow.id)); + resultPort.close(); + errorPort.close(); + isolate.kill(); + Timeline.finishSync(); + return result.future; +} + +@immutable +class _IsolateConfiguration<Q, R> { + const _IsolateConfiguration( + this.callback, + this.message, + this.resultPort, + this.debugLabel, + this.flowId, + ); + final isolates.ComputeCallback<Q, R> callback; + final Q message; + final SendPort resultPort; + final String debugLabel; + final int flowId; + + R apply() => callback(message); +} + +Future<void> _spawn<Q, R>(_IsolateConfiguration<Q, FutureOr<R>> configuration) async { + R result; + await Timeline.timeSync( + '${configuration.debugLabel}', + () async { result = await configuration.apply(); }, + flow: Flow.step(configuration.flowId), + ); + Timeline.timeSync( + '${configuration.debugLabel}: returning result', + () { configuration.resultPort.send(result); }, + flow: Flow.step(configuration.flowId), + ); +}
diff --git a/packages/flutter/lib/src/foundation/_isolates_web.dart b/packages/flutter/lib/src/foundation/_isolates_web.dart new file mode 100644 index 0000000..00f249f --- /dev/null +++ b/packages/flutter/lib/src/foundation/_isolates_web.dart
@@ -0,0 +1,14 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'isolates.dart' as isolates; + +/// The dart:html implementation of [isolate.compute]. +Future<R> compute<Q, R>(isolates.ComputeCallback<Q, R> callback, Q message, { String debugLabel }) async { + // To avoid blocking the UI immediately for an expensive function call, we + // pump a single frame to allow the framework to complete the current set + // of work. + await null; + return callback(message); +}
diff --git a/packages/flutter/lib/src/foundation/_platform_io.dart b/packages/flutter/lib/src/foundation/_platform_io.dart new file mode 100644 index 0000000..7726331 --- /dev/null +++ b/packages/flutter/lib/src/foundation/_platform_io.dart
@@ -0,0 +1,34 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:io'; +import 'assertions.dart'; +import 'platform.dart' as platform; + +/// The dart:io implementation of [platform.defaultTargetPlatform]. +platform.TargetPlatform get defaultTargetPlatform { + platform.TargetPlatform result; + if (Platform.isIOS) { + result = platform.TargetPlatform.iOS; + } else if (Platform.isAndroid) { + result = platform.TargetPlatform.android; + } else if (Platform.isFuchsia) { + result = platform.TargetPlatform.fuchsia; + } + assert(() { + if (Platform.environment.containsKey('FLUTTER_TEST')) + result = platform.TargetPlatform.android; + return true; + }()); + if (platform.debugDefaultTargetPlatformOverride != null) + result = platform.debugDefaultTargetPlatformOverride; + if (result == null) { + throw FlutterError( + 'Unknown platform.\n' + '${Platform.operatingSystem} was not recognized as a target platform. ' + 'Consider updating the list of TargetPlatforms to include this platform.' + ); + } + return result; +}
diff --git a/packages/flutter/lib/src/foundation/_platform_web.dart b/packages/flutter/lib/src/foundation/_platform_web.dart new file mode 100644 index 0000000..c020d36 --- /dev/null +++ b/packages/flutter/lib/src/foundation/_platform_web.dart
@@ -0,0 +1,16 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'platform.dart' as platform; + +/// The dart:html implementation of [platform.defaultTargetPlatform]. +platform.TargetPlatform get defaultTargetPlatform { + // To getter a better guess at the targetPlatform we need to be able to + // reference the window, but that won't be availible until we fix the + // platforms configuration for Flutter. + platform.TargetPlatform result = platform.TargetPlatform.android; + if (platform.debugDefaultTargetPlatformOverride != null) + result = platform.debugDefaultTargetPlatformOverride; + return result; +}
diff --git a/packages/flutter/lib/src/foundation/basic_types.dart b/packages/flutter/lib/src/foundation/basic_types.dart index 4713cc4..7760dd1 100644 --- a/packages/flutter/lib/src/foundation/basic_types.dart +++ b/packages/flutter/lib/src/foundation/basic_types.dart
@@ -8,7 +8,6 @@ // COMMON SIGNATURES export 'dart:ui' show VoidCallback; -export 'bitfield.dart' if (dart.library.html) 'bitfield_unsupported.dart'; /// Signature for callbacks that report that an underlying value has changed. ///
diff --git a/packages/flutter/lib/src/foundation/binding.dart b/packages/flutter/lib/src/foundation/binding.dart index a5e9f6e..5ab2145 100644 --- a/packages/flutter/lib/src/foundation/binding.dart +++ b/packages/flutter/lib/src/foundation/binding.dart
@@ -6,8 +6,8 @@ import 'dart:convert' show json; import 'dart:developer' as developer; import 'dart:io' show exit; -// Before adding any more dart:ui imports, pleaes read the README. import 'dart:ui' as ui show saveCompilationTrace, Window, window; +// Before adding any more dart:ui imports, please read the README. import 'package:meta/meta.dart';
diff --git a/packages/flutter/lib/src/foundation/bitfield.dart b/packages/flutter/lib/src/foundation/bitfield.dart index b4b3b11..8ca3829 100644 --- a/packages/flutter/lib/src/foundation/bitfield.dart +++ b/packages/flutter/lib/src/foundation/bitfield.dart
@@ -2,25 +2,26 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '_bitfield_io.dart' + if (dart.library.html) '_bitfield_web.dart' as _bitfield; + /// The largest SMI value. /// -/// See <https://dart.dev/articles/numeric-computation/#smis-and-mints> +/// See <https://www.dartlang.org/articles/numeric-computation/#smis-and-mints> /// /// When compiling to JavaScript, this value is not supported since it is /// larger than the maximum safe 32bit integer. -const int kMaxUnsignedSMI = 0x3FFFFFFFFFFFFFFF; +const int kMaxUnsignedSMI = _bitfield.kMaxUnsignedSMI; /// A BitField over an enum (or other class whose values implement "index"). /// Only the first 62 values of the enum can be used as indices. /// /// When compiling to JavaScript, this class is not supported. -class BitField<T extends dynamic> { +abstract class BitField<T extends dynamic> { /// Creates a bit field of all zeros. /// /// The given length must be at most 62. - BitField(this._length) - : assert(_length <= _smiBits), - _bits = _allZeros; + factory BitField(int length) = _bitfield.BitField<T>; /// Creates a bit field filled with a particular value. /// @@ -28,40 +29,20 @@ /// the bits are filled with zeros. /// /// The given length must be at most 62. - BitField.filled(this._length, bool value) - : assert(_length <= _smiBits), - _bits = value ? _allOnes : _allZeros; - - final int _length; - int _bits; - - static const int _smiBits = 62; // see https://dart.dev/articles/numeric-computation/#smis-and-mints - static const int _allZeros = 0; - static const int _allOnes = kMaxUnsignedSMI; // 2^(_kSMIBits+1)-1 + factory BitField.filled(int length, bool value) = _bitfield.BitField<T>.filled; /// Returns whether the bit with the given index is set to one. - bool operator [](T index) { - assert(index.index < _length); - return (_bits & 1 << index.index) > 0; - } + bool operator [](T index); /// Sets the bit with the given index to the given value. /// /// If value is true, the bit with the given index is set to one. Otherwise, /// the bit is set to zero. - void operator []=(T index, bool value) { - assert(index.index < _length); - if (value) - _bits = _bits | (1 << index.index); - else - _bits = _bits & ~(1 << index.index); - } + void operator []=(T index, bool value); /// Sets all the bits to the given value. /// /// If the value is true, the bits are all set to one. Otherwise, the bits are /// all set to zero. Defaults to setting all the bits to zero. - void reset([ bool value = false ]) { - _bits = value ? _allOnes : _allZeros; - } + void reset([ bool value = false ]); }
diff --git a/packages/flutter/lib/src/foundation/isolates.dart b/packages/flutter/lib/src/foundation/isolates.dart index 8afeb86..d0f2d3c 100644 --- a/packages/flutter/lib/src/foundation/isolates.dart +++ b/packages/flutter/lib/src/foundation/isolates.dart
@@ -3,12 +3,9 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:developer' show Timeline, Flow; -import 'dart:isolate'; -import 'package:meta/meta.dart'; - -import 'constants.dart'; +import '_isolates_io.dart' + if (dart.library.html) '_isolates_web.dart' as _isolates; /// Signature for the callback passed to [compute]. /// @@ -20,6 +17,9 @@ /// {@macro flutter.foundation.compute.limitations} typedef ComputeCallback<Q, R> = FutureOr<R> Function(Q message); +// The signature of [compute]. +typedef _ComputeImpl = Future<R> Function<Q, R>(ComputeCallback<Q, R> callback, Q message, { String debugLabel }); + /// Spawn an isolate, run `callback` on that isolate, passing it `message`, and /// (eventually) return the value returned by `callback`. /// @@ -44,82 +44,6 @@ /// /// The `debugLabel` argument can be specified to provide a name to add to the /// [Timeline]. This is useful when profiling an application. -Future<R> compute<Q, R>(ComputeCallback<Q, R> callback, Q message, { String debugLabel }) async { - if (!kReleaseMode) { - debugLabel ??= callback.toString(); - } - final Flow flow = Flow.begin(); - Timeline.startSync('$debugLabel: start', flow: flow); - final ReceivePort resultPort = ReceivePort(); - final ReceivePort errorPort = ReceivePort(); - Timeline.finishSync(); - final Isolate isolate = await Isolate.spawn<_IsolateConfiguration<Q, FutureOr<R>>>( - _spawn, - _IsolateConfiguration<Q, FutureOr<R>>( - callback, - message, - resultPort.sendPort, - debugLabel, - flow.id, - ), - errorsAreFatal: true, - onExit: resultPort.sendPort, - onError: errorPort.sendPort, - ); - final Completer<R> result = Completer<R>(); - errorPort.listen((dynamic errorData) { - assert(errorData is List<dynamic>); - assert(errorData.length == 2); - final Exception exception = Exception(errorData[0]); - final StackTrace stack = StackTrace.fromString(errorData[1]); - if (result.isCompleted) { - Zone.current.handleUncaughtError(exception, stack); - } else { - result.completeError(exception, stack); - } - }); - resultPort.listen((dynamic resultData) { - assert(resultData == null || resultData is R); - if (!result.isCompleted) - result.complete(resultData); - }); - await result.future; - Timeline.startSync('$debugLabel: end', flow: Flow.end(flow.id)); - resultPort.close(); - errorPort.close(); - isolate.kill(); - Timeline.finishSync(); - return result.future; -} - -@immutable -class _IsolateConfiguration<Q, R> { - const _IsolateConfiguration( - this.callback, - this.message, - this.resultPort, - this.debugLabel, - this.flowId, - ); - final ComputeCallback<Q, R> callback; - final Q message; - final SendPort resultPort; - final String debugLabel; - final int flowId; - - R apply() => callback(message); -} - -Future<void> _spawn<Q, R>(_IsolateConfiguration<Q, FutureOr<R>> configuration) async { - R result; - await Timeline.timeSync( - '${configuration.debugLabel}', - () async { result = await configuration.apply(); }, - flow: Flow.step(configuration.flowId), - ); - Timeline.timeSync( - '${configuration.debugLabel}: returning result', - () { configuration.resultPort.send(result); }, - flow: Flow.step(configuration.flowId), - ); -} +// Remove when https://github.com/dart-lang/sdk/issues/37149 is fixed. +// ignore: prefer_const_declarations +final _ComputeImpl compute = _isolates.compute;
diff --git a/packages/flutter/lib/src/foundation/platform.dart b/packages/flutter/lib/src/foundation/platform.dart index aaf6529..90b618a 100644 --- a/packages/flutter/lib/src/foundation/platform.dart +++ b/packages/flutter/lib/src/foundation/platform.dart
@@ -2,23 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:io' show Platform; - -import 'assertions.dart'; - -/// The platform that user interaction should adapt to target. -/// -/// The [defaultTargetPlatform] getter returns the current platform. -enum TargetPlatform { - /// Android: <https://www.android.com/> - android, - - /// Fuchsia: <https://fuchsia.googlesource.com/> - fuchsia, - - /// iOS: <http://www.apple.com/ios/> - iOS, -} +import '_platform_io.dart' + if (dart.library.html) '_platform_web.dart' as _platform; /// The [TargetPlatform] that matches the platform on which the framework is /// currently executing. @@ -48,36 +33,20 @@ // that would mean we'd be stuck with that platform forever emulating the other, // and we'd never be able to introduce dedicated behavior for that platform // (since doing so would be a big breaking change). -TargetPlatform get defaultTargetPlatform { - // TODO(jonahwilliams): consider where this constant should live. - const bool kIsWeb = identical(1, 1.0); - TargetPlatform result; - if (kIsWeb) { - result = TargetPlatform.android; - } else { - if (Platform.isIOS) { - result = TargetPlatform.iOS; - } else if (Platform.isAndroid) { - result = TargetPlatform.android; - } else if (Platform.isFuchsia) { - result = TargetPlatform.fuchsia; - } - } - assert(() { - if (!kIsWeb && Platform.environment.containsKey('FLUTTER_TEST')) - result = TargetPlatform.android; - return true; - }()); - if (debugDefaultTargetPlatformOverride != null) - result = debugDefaultTargetPlatformOverride; - if (result == null) { - throw FlutterError( - 'Unknown platform.\n' - '${Platform.operatingSystem} was not recognized as a target platform. ' - 'Consider updating the list of TargetPlatforms to include this platform.' - ); - } - return result; +TargetPlatform get defaultTargetPlatform => _platform.defaultTargetPlatform; + +/// The platform that user interaction should adapt to target. +/// +/// The [defaultTargetPlatform] getter returns the current platform. +enum TargetPlatform { + /// Android: <https://www.android.com/> + android, + + /// Fuchsia: <https://fuchsia.googlesource.com/> + fuchsia, + + /// iOS: <http://www.apple.com/ios/> + iOS, } /// Override the [defaultTargetPlatform].
diff --git a/packages/flutter/lib/src/foundation/profile.dart b/packages/flutter/lib/src/foundation/profile.dart index d1d5ff2..f063c74 100644 --- a/packages/flutter/lib/src/foundation/profile.dart +++ b/packages/flutter/lib/src/foundation/profile.dart
@@ -2,8 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' show VoidCallback; - +import 'basic_types.dart'; import 'constants.dart'; /// DEPRECATED. `function` cannot be treeshaken out of release builds.
diff --git a/packages/flutter/lib/src/painting/basic_types.dart b/packages/flutter/lib/src/painting/basic_types.dart index 0a1af23..7815f34 100644 --- a/packages/flutter/lib/src/painting/basic_types.dart +++ b/packages/flutter/lib/src/painting/basic_types.dart
@@ -41,10 +41,11 @@ TextPosition, TileMode, VertexMode, - VoidCallback, hashValues, hashList; +export 'package:flutter/foundation.dart' show VoidCallback; + // Intentionally not exported: // - Image, instantiateImageCodec, decodeImageFromList: // We use ui.* to make it very explicit that these are low-level image APIs.
diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart index 733db60..a8b674b 100644 --- a/packages/flutter/lib/src/rendering/object.dart +++ b/packages/flutter/lib/src/rendering/object.dart
@@ -9,7 +9,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/painting.dart'; -import 'package:flutter/scheduler.dart'; import 'package:flutter/semantics.dart'; import 'package:vector_math/vector_math_64.dart';
diff --git a/packages/flutter/lib/src/widgets/scroll_position_with_single_context.dart b/packages/flutter/lib/src/widgets/scroll_position_with_single_context.dart index 6c39b2b..7fc59bd 100644 --- a/packages/flutter/lib/src/widgets/scroll_position_with_single_context.dart +++ b/packages/flutter/lib/src/widgets/scroll_position_with_single_context.dart
@@ -7,7 +7,6 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/physics.dart'; import 'package:flutter/rendering.dart'; -import 'package:flutter/scheduler.dart'; import 'basic.dart'; import 'framework.dart';
diff --git a/packages/flutter/test/foundation/capture_output.dart b/packages/flutter/test/foundation/capture_output.dart index 8bd3bef..63fb5f4 100644 --- a/packages/flutter/test/foundation/capture_output.dart +++ b/packages/flutter/test/foundation/capture_output.dart
@@ -3,7 +3,7 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:ui' show VoidCallback; +import 'package:flutter/foundation.dart'; List<String> captureOutput(VoidCallback fn) { final List<String> log = <String>[];
diff --git a/packages/flutter/test/material/feedback_test.dart b/packages/flutter/test/material/feedback_test.dart index 603ed2c..d35b421 100644 --- a/packages/flutter/test/material/feedback_test.dart +++ b/packages/flutter/test/material/feedback_test.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. -import 'dart:ui'; - import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart';