Unverified Commit 44e228eb authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Move image logic from services/ to painting/. (#13409)

This allows the scheduler library to depend on the services library
and the painting library to depend on the scheduler library without
the services library having to depend on the scheduler library.

While I was at it I also cleaned up some of the binding logic: the
licenses logic can now be overridden (and the test library does so),
and the image cache can now be overridden as well.
parent 64feb95a
......@@ -3,7 +3,7 @@ import 'package:flutter/foundation.dart' show ValueGetter;
import 'package:http/http.dart' as http;
import 'package:http/testing.dart' as http;
import '../../../packages/flutter/test/services/image_data.dart';
import '../../../packages/flutter/test/painting/image_data.dart';
// Returns a mock HTTP client that responds with an image to all requests.
ValueGetter<http.Client> createMockImageHttpClient = () {
......
......@@ -19,6 +19,7 @@ library painting;
export 'src/painting/alignment.dart';
export 'src/painting/basic_types.dart';
export 'src/painting/binding.dart';
export 'src/painting/border_radius.dart';
export 'src/painting/borders.dart';
export 'src/painting/box_border.dart';
......@@ -28,12 +29,17 @@ export 'src/painting/box_shadow.dart';
export 'src/painting/circle_border.dart';
export 'src/painting/colors.dart';
export 'src/painting/decoration.dart';
export 'src/painting/decoration_image.dart';
export 'src/painting/edge_insets.dart';
export 'src/painting/flutter_logo.dart';
export 'src/painting/fractional_offset.dart';
export 'src/painting/geometry.dart';
export 'src/painting/gradient.dart';
export 'src/painting/images.dart';
export 'src/painting/image_cache.dart';
export 'src/painting/image_decoder.dart';
export 'src/painting/image_provider.dart';
export 'src/painting/image_resolution.dart';
export 'src/painting/image_stream.dart';
export 'src/painting/matrix_utils.dart';
export 'src/painting/rounded_rectangle_border.dart';
export 'src/painting/shape_decoration.dart';
......
......@@ -6,20 +6,19 @@
///
/// To use, import `package:flutter/rendering.dart`.
///
/// The [RenderObject] hierarchy is used by the Flutter Widgets
/// library to implement its layout and painting back-end. Generally,
/// while you may use custom [RenderBox] classes for specific effects
/// in your applications, most of the time your only interaction with
/// the [RenderObject] hierarchy will be in debugging layout issues.
/// The [RenderObject] hierarchy is used by the Flutter Widgets library to
/// implement its layout and painting back-end. Generally, while you may use
/// custom [RenderBox] classes for specific effects in your applications, most
/// of the time your only interaction with the [RenderObject] hierarchy will be
/// in debugging layout issues.
///
/// If you are developing your own library or application directly on
/// top of the rendering library, then you will want to have a binding
/// (see [BindingBase]). You can use [RenderingFlutterBinding], or you
/// can create your own binding. If you create your own binding, it
/// needs to import at least [SchedulerBinding], [GestureBinding],
/// [ServicesBinding], and [RendererBinding]. The rendering library
/// does not automatically create a binding, but relies on one being
/// initialized with those features.
/// If you are developing your own library or application directly on top of the
/// rendering library, then you will want to have a binding (see [BindingBase]).
/// You can use [RenderingFlutterBinding], or you can create your own binding.
/// If you create your own binding, it needs to import at least
/// [ServicesBinding], [GestureBinding], [SchedulerBinding], [PaintingBinding],
/// and [RendererBinding]. The rendering library does not automatically create a
/// binding, but relies on one being initialized with those features.
library rendering;
export 'package:flutter/foundation.dart' show
......
......@@ -15,11 +15,6 @@ export 'src/services/binding.dart';
export 'src/services/clipboard.dart';
export 'src/services/haptic_feedback.dart';
export 'src/services/http_client.dart';
export 'src/services/image_cache.dart';
export 'src/services/image_decoder.dart';
export 'src/services/image_provider.dart';
export 'src/services/image_resolution.dart';
export 'src/services/image_stream.dart';
export 'src/services/message_codec.dart';
export 'src/services/message_codecs.dart';
export 'src/services/platform_channel.dart';
......
......@@ -26,19 +26,17 @@ typedef Future<Map<String, String>> ServiceExtensionCallback(Map<String, String>
/// "bindings").
///
/// To use this class in a mixin, inherit from it and implement
/// [initInstances()]. The mixin is guaranteed to only be constructed
/// once in the lifetime of the app (more precisely, it will assert if
/// constructed twice in checked mode).
/// [initInstances()]. The mixin is guaranteed to only be constructed once in
/// the lifetime of the app (more precisely, it will assert if constructed twice
/// in checked mode).
///
/// The top-most layer used to write the application will have a
/// concrete class that inherits from BindingBase and uses all the
/// various BindingBase mixins (such as [ServicesBinding]). For example, the
/// Widgets library in flutter introduces a binding called
/// [WidgetsFlutterBinding]. The relevant library defines how to create
/// the binding. It could be implied (for example,
/// [WidgetsFlutterBinding] is automatically started from [runApp]), or
/// the application might be required to explicitly call the
/// constructor.
/// The top-most layer used to write the application will have a concrete class
/// that inherits from [BindingBase] and uses all the various [BindingBase]
/// mixins (such as [ServicesBinding]). For example, the Widgets library in
/// Flutter introduces a binding called [WidgetsFlutterBinding]. The relevant
/// library defines how to create the binding. It could be implied (for example,
/// [WidgetsFlutterBinding] is automatically started from [runApp]), or the
/// application might be required to explicitly call the constructor.
abstract class BindingBase {
/// Default abstract constructor for bindings.
///
......@@ -106,15 +104,15 @@ abstract class BindingBase {
assert(!_debugServiceExtensionsRegistered);
registerSignalServiceExtension(
name: 'reassemble',
callback: reassembleApplication
callback: reassembleApplication,
);
registerSignalServiceExtension(
name: 'exit',
callback: _exitApplication
callback: _exitApplication,
);
registerSignalServiceExtension(
name: 'frameworkPresent',
callback: () => new Future<Null>.value()
callback: () => new Future<Null>.value(),
);
assert(() {
registerServiceExtension(
......
......@@ -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 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'colors.dart';
......
......@@ -5,7 +5,6 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'colors.dart';
......
// Copyright 2016 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 'package:flutter/foundation.dart';
import 'package:flutter/services.dart' show ServicesBinding;
import 'image_cache.dart';
/// Binding for the painting library.
///
/// Hooks into the cache eviction logic to clear the image cache.
///
/// Requires the [ServicesBinding] to be mixed in earlier.
abstract class PaintingBinding extends BindingBase with ServicesBinding {
// This class is intended to be used as a mixin, and should not be
// extended directly.
factory PaintingBinding._() => null;
@override
void initInstances() {
super.initInstances();
_instance = this;
_imageCache = createImageCache();
}
/// The current [PaintingBinding], if one has been created.
static PaintingBinding get instance => _instance;
static PaintingBinding _instance;
/// The singleton that implements the Flutter framework's image cache.
///
/// The cache is used internally by [ImageProvider] and should generally not
/// be accessed directly.
///
/// The image cache is created during startup by the [createImageCache]
/// method.
ImageCache get imageCache => _imageCache;
ImageCache _imageCache;
/// Creates the [ImageCache] singleton (accessible via [imageCache]).
///
/// This method can be overridden to provide a custom image cache.
@protected
ImageCache createImageCache() => new ImageCache();
@override
void evict(String asset) {
super.evict(asset);
imageCache.clear();
}
}
/// The singleton that implements the Flutter framework's image cache.
///
/// The cache is used internally by [ImageProvider] and should generally not be
/// accessed directly.
///
/// The image cache is created during startup by the [PaintingBinding]'s
/// [PaintingBinding.createImageCache] method.
ImageCache get imageCache => PaintingBinding.instance.imageCache;
......@@ -5,16 +5,16 @@
import 'dart:math' as math;
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'basic_types.dart';
import 'border_radius.dart';
import 'box_border.dart';
import 'box_shadow.dart';
import 'decoration.dart';
import 'decoration_image.dart';
import 'edge_insets.dart';
import 'gradient.dart';
import 'images.dart';
import 'image_provider.dart';
/// An immutable description of how to paint a box.
///
......
......@@ -3,12 +3,10 @@
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'basic_types.dart';
import 'edge_insets.dart';
export 'package:flutter/services.dart' show ImageConfiguration;
import 'image_provider.dart';
// This group of classes is intended for painting in cartesian coordinates.
......
......@@ -5,12 +5,13 @@
import 'dart:ui' as ui show Image;
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'alignment.dart';
import 'basic_types.dart';
import 'borders.dart';
import 'box_fit.dart';
import 'image_provider.dart';
import 'image_stream.dart';
/// How to paint any portions of a box not covered by an image.
enum ImageRepeat {
......
......@@ -6,7 +6,6 @@ import 'dart:math' as math;
import 'dart:typed_data';
import 'dart:ui' as ui show Gradient, TextBox, lerpDouble;
import 'package:flutter/services.dart';
import 'package:flutter/foundation.dart';
import 'alignment.dart';
......@@ -14,6 +13,7 @@ import 'basic_types.dart';
import 'box_fit.dart';
import 'decoration.dart';
import 'edge_insets.dart';
import 'image_provider.dart';
import 'text_painter.dart';
import 'text_span.dart';
import 'text_style.dart';
......
......@@ -89,9 +89,3 @@ class ImageCache {
return result;
}
}
/// The singleton that implements the Flutter framework's image cache.
///
/// The cache is used internally by [ImageProvider] and should generally not be
/// accessed directly.
final ImageCache imageCache = new ImageCache();
......@@ -9,11 +9,10 @@ import 'dart:ui' as ui show instantiateImageCodec, Codec;
import 'dart:ui' show Size, Locale, TextDirection, hashValues;
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'asset_bundle.dart';
import 'http_client.dart';
import 'image_cache.dart';
import 'binding.dart';
import 'image_stream.dart';
/// Configuration information passed to the [ImageProvider.resolve] method to
......@@ -262,7 +261,7 @@ abstract class ImageProvider<T> {
T obtainedKey;
obtainKey(configuration).then<Null>((T key) {
obtainedKey = key;
stream.setCompleter(imageCache.putIfAbsent(key, () => load(key)));
stream.setCompleter(PaintingBinding.instance.imageCache.putIfAbsent(key, () => load(key)));
}).catchError(
(dynamic exception, StackTrace stack) async {
FlutterError.reportError(new FlutterErrorDetails(
......
......@@ -8,8 +8,8 @@ import 'dart:convert';
import 'dart:ui' show hashValues;
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'asset_bundle.dart';
import 'image_provider.dart';
const String _kAssetManifestFileName = 'AssetManifest.json';
......
......@@ -3,7 +3,6 @@
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'basic_types.dart';
import 'borders.dart';
......@@ -12,9 +11,10 @@ import 'box_decoration.dart';
import 'box_shadow.dart';
import 'circle_border.dart';
import 'decoration.dart';
import 'decoration_image.dart';
import 'edge_insets.dart';
import 'gradient.dart';
import 'images.dart';
import 'image_provider.dart';
import 'rounded_rectangle_border.dart';
/// An immutable description of how to paint an arbitrary shape.
......
......@@ -20,7 +20,7 @@ import 'view.dart';
export 'package:flutter/gestures.dart' show HitTestResult;
/// The glue between the render tree and the Flutter engine.
abstract class RendererBinding extends BindingBase with SchedulerBinding, ServicesBinding, HitTestable {
abstract class RendererBinding extends BindingBase with ServicesBinding, SchedulerBinding, HitTestable {
// This class is intended to be used as a mixin, and should not be
// extended directly.
factory RendererBinding._() => null;
......@@ -347,7 +347,7 @@ void debugDumpSemanticsTree(DebugSemanticsDumpOrder childOrder) {
/// that layer's binding.
///
/// See also [BindingBase].
class RenderingFlutterBinding extends BindingBase with SchedulerBinding, GestureBinding, ServicesBinding, RendererBinding {
class RenderingFlutterBinding extends BindingBase with GestureBinding, ServicesBinding, SchedulerBinding, RendererBinding {
/// Creates a binding for the rendering layer.
///
/// The `root` render box is attached directly to the [renderView] and is
......
......@@ -8,7 +8,6 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/semantics.dart';
import 'package:flutter/services.dart';
import 'package:vector_math/vector_math_64.dart';
......
......@@ -8,14 +8,14 @@ import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'asset_bundle.dart';
import 'image_cache.dart';
import 'platform_messages.dart';
/// Listens for platform messages and directs them to [BinaryMessages].
///
/// The ServicesBinding also registers a [LicenseEntryCollector] that exposes
/// The [ServicesBinding] also registers a [LicenseEntryCollector] that exposes
/// the licenses found in the `LICENSE` file stored at the root of the asset
/// bundle.
/// bundle, and implements the `ext.flutter.evict` service extension (see
/// [evict]).
abstract class ServicesBinding extends BindingBase {
// This class is intended to be used as a mixin, and should not be
// extended directly.
......@@ -26,6 +26,16 @@ abstract class ServicesBinding extends BindingBase {
super.initInstances();
ui.window
..onPlatformMessage = BinaryMessages.handlePlatformMessage;
initLicenses();
}
/// Adds relevant licenses to the [LicenseRegistry].
///
/// By default, the [ServicesBinding]'s implementation of [initLicenses] adds
/// all the licenses collected by the `flutter` tool during compilation.
@protected
@mustCallSuper
void initLicenses() {
LicenseRegistry.addLicense(_addLicenses);
}
......@@ -51,16 +61,25 @@ abstract class ServicesBinding extends BindingBase {
void initServiceExtensions() {
super.initServiceExtensions();
registerStringServiceExtension(
// ext.flutter.evict value=foo.png will cause foo.png to be evicted from the rootBundle cache
// and cause the entire image cache to be cleared. This is used by hot reload mode to clear
// out the cache of resources that have changed.
// TODO(ianh): find a way to only evict affected images, not all images
// ext.flutter.evict value=foo.png will cause foo.png to be evicted from
// the rootBundle cache and cause the entire image cache to be cleared.
// This is used by hot reload mode to clear out the cache of resources
// that have changed.
name: 'evict',
getter: () async => '',
setter: (String value) async {
rootBundle.evict(value);
imageCache.clear();
evict(value);
}
);
}
/// Called in response to the `ext.flutter.evict` service extension.
///
/// This is used by the `flutter` tool during hot reload so that any images
/// that have changed on disk get cleared from caches.
@protected
@mustCallSuper
void evict(String asset) {
rootBundle.evict(asset);
}
}
......@@ -891,7 +891,7 @@ class RenderObjectToWidgetElement<T extends RenderObject> extends RootRenderObje
/// A concrete binding for applications based on the Widgets framework.
/// This is the glue that binds the framework to the Flutter engine.
class WidgetsFlutterBinding extends BindingBase with SchedulerBinding, GestureBinding, ServicesBinding, RendererBinding, WidgetsBinding {
class WidgetsFlutterBinding extends BindingBase with GestureBinding, ServicesBinding, SchedulerBinding, PaintingBinding, RendererBinding, WidgetsBinding {
/// Returns an instance of the [WidgetsBinding], creating and
/// initializing it if necessary. If one is created, it will be a
......
......@@ -7,6 +7,7 @@ import 'dart:io' show File;
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/services.dart';
import 'basic.dart';
......@@ -15,13 +16,16 @@ import 'localizations.dart';
import 'media_query.dart';
import 'ticker_provider.dart';
export 'package:flutter/services.dart' show
ImageProvider,
export 'package:flutter/painting.dart' show
AssetImage,
ExactAssetImage,
FileImage,
ImageConfiguration,
ImageInfo,
ImageStream,
ImageProvider,
MemoryImage,
NetworkImage,
FileImage;
NetworkImage;
/// Creates an [ImageConfiguration] based on the given [BuildContext] (and
/// optionally size).
......
......@@ -3,7 +3,6 @@
// found in the LICENSE file.
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'basic.dart';
import 'framework.dart';
......
......@@ -5,7 +5,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter_test/flutter_test.dart';
import '../services/mocks_for_image_cache.dart';
import '../painting/mocks_for_image_cache.dart';
Future<Null> pumpWidgetWithBoilerplate(WidgetTester tester, Widget widget) async {
await tester.pumpWidget(
......
......@@ -5,7 +5,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter_test/flutter_test.dart';
import '../services/mocks_for_image_cache.dart';
import '../painting/mocks_for_image_cache.dart';
/// Integration tests testing both [CupertinoPageScaffold] and [CupertinoTabScaffold].
void main() {
......
......@@ -5,8 +5,8 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter_test/flutter_test.dart';
import '../painting/mocks_for_image_cache.dart';
import '../rendering/rendering_tester.dart';
import '../services/mocks_for_image_cache.dart';
List<int> selectedTabs;
......
......@@ -16,9 +16,10 @@ import 'package:flutter/widgets.dart';
import 'package:test/test.dart';
class TestServiceExtensionsBinding extends BindingBase
with SchedulerBinding,
ServicesBinding,
with ServicesBinding,
GestureBinding,
SchedulerBinding,
PaintingBinding,
RendererBinding,
WidgetsBinding {
......
......@@ -7,11 +7,11 @@ import 'dart:ui' as ui show Image, ColorFilter;
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/services.dart';
import 'package:quiver/testing/async.dart';
import 'package:test/test.dart';
import '../services/mocks_for_image_cache.dart';
import '../painting/mocks_for_image_cache.dart';
import '../rendering/rendering_tester.dart';
class TestCanvas implements Canvas {
TestCanvas([this.invocations]);
......@@ -90,6 +90,8 @@ class TestImage extends ui.Image {
}
void main() {
new TestRenderingFlutterBinding(); // initializes the imageCache
test('Decoration.lerp()', () {
final BoxDecoration a = const BoxDecoration(color: const Color(0xFFFFFFFF));
final BoxDecoration b = const BoxDecoration(color: const Color(0x00000000));
......
......@@ -6,7 +6,7 @@ import 'dart:async';
import 'dart:ui' as ui show Codec;
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter/painting.dart';
/// An image provider implementation for testing that is using a [ui.Codec]
/// that it was given at construction time (typically the job of real image
......
......@@ -2,13 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/services.dart';
import 'package:flutter/painting.dart';
import 'package:test/test.dart';
import '../rendering/rendering_tester.dart';
import 'mocks_for_image_cache.dart';
void main() {
test('Image cache resizing', () async {
new TestRenderingFlutterBinding(); // initializes the imageCache
test('Image cache resizing', () async {
imageCache.maximumSize = 2;
......
......@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/services.dart';
import 'package:flutter/painting.dart';
import 'package:test/test.dart';
import '../rendering/rendering_tester.dart';
import 'mocks_for_image_cache.dart';
void main() {
new TestRenderingFlutterBinding(); // initializes the imageCache
test('Image cache', () async {
imageCache.maximumSize = 3;
......
......@@ -5,7 +5,7 @@
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/services.dart';
import 'package:flutter/painting.dart';
import 'package:test/test.dart';
import 'image_data.dart';
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/services.dart';
import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
......
......@@ -4,8 +4,9 @@
import 'dart:async';
import 'dart:ui';
import 'package:flutter/painting.dart';
import 'package:flutter/scheduler.dart' show timeDilation;
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
class FakeFrameInfo extends FrameInfo {
......
......@@ -7,7 +7,7 @@ import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter/painting.dart';
import 'image_data.dart';
......
......@@ -6,7 +6,7 @@ import 'dart:async';
import 'dart:ui' as ui show Image;
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter/painting.dart';
class TestImageInfo implements ImageInfo {
const TestImageInfo(this.value, { this.image, this.scale });
......
......@@ -6,12 +6,14 @@ import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import '../rendering/mock_canvas.dart';
import '../rendering/rendering_tester.dart';
void main() {
new TestRenderingFlutterBinding(); // initializes the imageCache
test('ShapeDecoration constructor', () {
final Color colorR = const Color(0xffff0000);
final Color colorG = const Color(0xff00ff00);
......
......@@ -11,7 +11,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart' show EnginePhase;
export 'package:flutter_test/flutter_test.dart' show EnginePhase;
class TestRenderingFlutterBinding extends BindingBase with SchedulerBinding, ServicesBinding, RendererBinding, GestureBinding {
class TestRenderingFlutterBinding extends BindingBase with ServicesBinding, GestureBinding, SchedulerBinding, PaintingBinding, RendererBinding {
EnginePhase phase = EnginePhase.composite;
@override
......
......@@ -7,6 +7,7 @@ import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
......
......@@ -7,7 +7,7 @@ import 'dart:ui' as ui;
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import '../services/image_test_utils.dart';
import '../painting/image_test_utils.dart';
Future<Null> main() async {
// These must run outside test zone to complete
......
......@@ -10,7 +10,7 @@ import 'package:http/http.dart' as http;
import 'package:http/testing.dart' as http;
import 'package:flutter/services.dart' show createHttpClient;
import '../services/image_data.dart';
import '../painting/image_data.dart';
void main() {
testWidgets('Headers', (WidgetTester tester) async {
......
......@@ -3,11 +3,10 @@
// found in the LICENSE file.
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import '../services/mocks_for_image_cache.dart';
import '../painting/mocks_for_image_cache.dart';
const ImageProvider _kImage = const TestImageProvider(21, 42);
......
......@@ -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 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
......
......@@ -6,7 +6,6 @@ import 'dart:async';
import 'dart:ui' as ui show Image;
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
......
......@@ -8,11 +8,10 @@ import 'dart:ui' as ui show Image;
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import '../services/image_data.dart';
import '../painting/image_data.dart';
void main() {
testWidgets('Verify Image resets its RenderImage when changing providers', (WidgetTester tester) async {
......
......@@ -9,9 +9,9 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import '../services/fake_codec.dart';
import '../services/fake_image_provider.dart';
import '../services/image_data.dart';
import '../painting/fake_codec.dart';
import '../painting/fake_image_provider.dart';
import '../painting/image_data.dart';
Future<Null> main() async {
final FakeCodec fakeCodec = await FakeCodec.fromData(new Uint8List.fromList(kAnimatedGif));
......
......@@ -35,7 +35,7 @@ const String _extensionMethod = 'ext.flutter.$_extensionMethodName';
/// eventually completes to a string response.
typedef Future<String> DataHandler(String message);
class _DriverBinding extends BindingBase with SchedulerBinding, GestureBinding, ServicesBinding, RendererBinding, WidgetsBinding {
class _DriverBinding extends BindingBase with ServicesBinding, SchedulerBinding, GestureBinding, PaintingBinding, RendererBinding, WidgetsBinding {
_DriverBinding(this._handler);
final DataHandler _handler;
......
......@@ -86,7 +86,8 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
with SchedulerBinding,
GestureBinding,
RendererBinding,
// Services binding omitted to avoid dragging in the licenses code.
ServicesBinding,
PaintingBinding,
WidgetsBinding {
/// Constructor for [TestWidgetsFlutterBinding].
......@@ -150,6 +151,12 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
super.initInstances();
}
@override
void initLicenses() {
// Do not include any licenses, because we're a test, and the LICENSE file
// doesn't get generated for tests.
}
/// Whether there is currently a test executing.
bool get inTest;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment