diff --git a/packages/flutter/lib/shell.dart b/packages/flutter/lib/shell.dart index 35e27127c1f..59571e7bd98 100644 --- a/packages/flutter/lib/shell.dart +++ b/packages/flutter/lib/shell.dart @@ -13,13 +13,17 @@ import 'package:mojo/core.dart' as core; import 'package:mojo/mojo/service_provider.mojom.dart' as mojom; import 'package:mojo/mojo/shell.mojom.dart' as mojom; -/// A replacement for shell.connectToService. Implementations should return true -/// if they handled the request, or false if the request should fall through -/// to the default requestService. +/// Signature for replacements for [shell.connectToService]. Implementations +/// should return true if they handled the request, or false if the request +/// should fall through to the default requestService. typedef bool OverrideConnectToService(String url, Object proxy); /// Manages connections with embedder-provided services. class MojoShell { + /// Creates the MojoShell singleton. This constructor can only be called once. + /// If your application uses bindings, it is called by the [Services] binding. + /// (See [BindingBase] for more details on bindings. Any application using + /// the Flutter 'rendering' or 'widgets' libraries uses a binding.) MojoShell() { assert(_instance == null); _instance = this; @@ -52,6 +56,8 @@ class MojoShell { bool get canConnectToOtherApplications => _shell != null; /// Attempts to connect to an application via the Mojo shell. + /// + /// Returns null if [canConnectToOtherApplications] is false. ApplicationConnection connectToApplication(String url) { if (_shell == null) return null; @@ -61,13 +67,33 @@ class MojoShell { return new ApplicationConnection(exposedServices, services); } - /// Set this to intercept calls to [connectToService()] and supply an - /// alternative implementation of a service (for example, a mock for testing). + /// Interceptor for calls to [connectToService] and + /// [connectToViewAssociatedService] so that tests can supply alternative + /// implementations of services (for example, a mock for testing). OverrideConnectToService overrideConnectToService; - /// Attempts to connect to a service implementing the interface for the given proxy. - /// If an application URL is specified, the service will be requested from that application. - /// Otherwise, it will be requested from the embedder (the Flutter engine). + /// Attempts to connect to a service implementing the interface for the given + /// proxy. If an application URL is specified and + /// [canConnectToOtherApplications] is true, the service will be requested + /// from that application. Otherwise, it will be requested from the embedder + /// (the Flutter engine). + /// + /// For example, suppose there was a service of type `Foo` that was normally + /// hosted with the URL "mojo:foo" and that was also provided by the Flutter + /// embedder when there is no shell (i.e. when [canConnectToOtherApplications] + /// returns false). The following code (assuming the relevant mojom file + /// declaring `Foo` was imported with the prefix `mojom`) would connect to it, + /// and then invoke the method `bar()` on it: + /// + /// ```dart + /// mojom.FooProxy foo = new mojom.FooProxy.unbound(); + /// shell.connectToService("mojo:foo", foo); + /// foo.ptr.bar(); + /// ``` + /// + /// For examples of mojom files, see the `sky_services` package. + /// + /// See also [connectToViewAssociatedService]. void connectToService(String url, bindings.ProxyBase proxy) { if (overrideConnectToService != null && overrideConnectToService(url, proxy)) return; @@ -100,6 +126,27 @@ class MojoShell { } final mojom.ServiceProviderProxy _viewServices = _takeViewServices(); + /// Attempts to connect to a service provided specifically for the current + /// view by the embedder or host platform. + /// + /// For example, keyboard services are specific to a view; you can only + /// receive keyboard input when the application's view is the one with focus. + /// + /// For example, suppose there was a service of type `Foo` that was provided + /// on a view-by-view basis by the embedder or host platform. The following + /// code (assuming the relevant mojom file declaring `Foo` was imported with + /// the prefix `mojom`) would connect to it, and then invoke the method + /// `bar()` on it: + /// + /// ```dart + /// mojom.FooProxy foo = new mojom.FooProxy.unbound(); + /// shell.connectToViewAssociatedService(foo); + /// foo.ptr.bar(); + /// ``` + /// + /// For examples of mojom files, see the `sky_services` package. + /// + /// See also [connectToService]. void connectToViewAssociatedService(bindings.ProxyBase proxy) { if (overrideConnectToService != null && overrideConnectToService(null, proxy)) return; @@ -111,6 +158,21 @@ class MojoShell { } /// Registers a service to expose to the embedder. + /// + /// For example, suppose a Flutter application wanted to provide a service + /// `Foo` to the embedder, that a mojom file declaring `Foo` was imported with + /// the prefix `mojom`, that `package:mojo/core.dart` was imported with the + /// prefix `core`, and that an implementation of the `Foo` service existed in + /// the class `MyFooImplementation`. The following code, run during the + /// binding initialization (i.e. during the same call stack as the call to the + /// [new MojoShell] constructor) would achieve this: + /// + /// ```dart + /// shell.provideService(mojom.Foo.serviceName, (core.MojoMessagePipeEndpoint endpoint) { + /// mojom.FooStub foo = new mojom.FooStub.fromEndpoint(endpoint); + /// foo.impl = new MyFooImplementation(); + /// }); + /// ``` void provideService(String interfaceName, ServiceFactory factory) { _embedderConnection?.provideService(interfaceName, factory); } diff --git a/packages/flutter/lib/src/animation/animation.dart b/packages/flutter/lib/src/animation/animation.dart index dfd48a7f044..06600059e16 100644 --- a/packages/flutter/lib/src/animation/animation.dart +++ b/packages/flutter/lib/src/animation/animation.dart @@ -19,6 +19,7 @@ enum AnimationStatus { completed, } +/// Signature for listeners attached using [Animation.addStatusListener]. typedef void AnimationStatusListener(AnimationStatus status); /// An animation with a value of type T @@ -36,8 +37,12 @@ typedef void AnimationStatusListener(AnimationStatus status); /// To create a new animation that you can run forward and backward, consider /// using [AnimationController]. abstract class Animation { + /// Abstract const constructor. This constructor enables subclasses to provide + /// const constructors so that they can be used in const expressions. const Animation(); + // keep these next five dartdocs in sync with the dartdocs in AnimationWithParentMixin + /// Calls the listener every time the value of the animation changes. void addListener(VoidCallback listener); @@ -66,6 +71,21 @@ abstract class Animation { String toString() { return '$runtimeType(${toStringDetails()})'; } + + /// Provides a string describing the status of this object, but not including + /// information about the object itself. + /// + /// This function is used by [Animation.toString] so that [Animation] + /// subclasses can provide additional details while ensuring all [Animation] + /// subclasses have a consistent [toString] style. + /// + /// The result of this function includes an icon describing the status of this + /// [Animation] object: + /// + /// * "▶": [AnimationStatus.forward] ([value] increasing) + /// * "◀": [AnimationStatus.reverse] ([value] decreasing) + /// * "⏭": [AnimationStatus.completed] ([value] == 1.0) + /// * "⏮": [AnimationStatus.dismissed] ([value] == 0.0) String toStringDetails() { assert(status != null); String icon; diff --git a/packages/flutter/lib/src/animation/animation_controller.dart b/packages/flutter/lib/src/animation/animation_controller.dart index 2a5b3ff96c8..38063591ac2 100644 --- a/packages/flutter/lib/src/animation/animation_controller.dart +++ b/packages/flutter/lib/src/animation/animation_controller.dart @@ -109,6 +109,13 @@ class AnimationController extends Animation @override double get value => _value; double _value; + /// Stops the animation controller and sets the current value of the + /// animation. + /// + /// The new value is clamped to the range set by [lowerBound] and [upperBound]. + /// + /// Value listeners are notified even if this does not change the value. + /// Status listeners are notified if the animation was previously playing. void set value(double newValue) { assert(newValue != null); stop(); diff --git a/packages/flutter/lib/src/animation/animations.dart b/packages/flutter/lib/src/animation/animations.dart index e92a6deedc0..035c603bc81 100644 --- a/packages/flutter/lib/src/animation/animations.dart +++ b/packages/flutter/lib/src/animation/animations.dart @@ -67,7 +67,16 @@ class _AlwaysDismissedAnimation extends Animation { const Animation kAlwaysDismissedAnimation = const _AlwaysDismissedAnimation(); /// An animation that is always stopped at a given value. +/// +/// The [status] is always [AnimationStatus.forward]. class AlwaysStoppedAnimation extends Animation { + /// Creates an [AlwaysStoppedAnimation] with the given value. + /// + /// Since the [value] and [status] of an [AlwaysStoppedAnimation] can never + /// change, the listeners can never be invoked. It is therefore safe to reuse + /// an [AlwaysStoppedAnimation] instance in multiple places. If the [value] to + /// be used is known at compile time, the constructor should be invoked as a + /// `const` constructor. const AlwaysStoppedAnimation(this.value); @override @@ -96,15 +105,25 @@ abstract class AnimationWithParentMixin { /// The animation whose value this animation will proxy. /// /// This animation must remain the same for the lifetime of this object. If - /// you wish to proxy a different animation at different times, conside using + /// you wish to proxy a different animation at different times, consider using /// [ProxyAnimation]. Animation get parent; + // keep these next five dartdocs in sync with the dartdocs in Animation + + /// Calls the listener every time the value of the animation changes. void addListener(VoidCallback listener) => parent.addListener(listener); + + /// Stop calling the listener every time the value of the animation changes. void removeListener(VoidCallback listener) => parent.removeListener(listener); + + /// Calls listener every time the status of the animation changes. void addStatusListener(AnimationStatusListener listener) => parent.addStatusListener(listener); + + /// Stops calling the listener every time the status of the animation changes. void removeStatusListener(AnimationStatusListener listener) => parent.removeStatusListener(listener); + /// The current status of this animation. AnimationStatus get status => parent.status; } diff --git a/packages/flutter/lib/src/animation/curves.dart b/packages/flutter/lib/src/animation/curves.dart index 07d47727845..e212e3e1325 100644 --- a/packages/flutter/lib/src/animation/curves.dart +++ b/packages/flutter/lib/src/animation/curves.dart @@ -16,6 +16,8 @@ const double _kCubicErrorBound = 0.001; /// /// See [Curves] for a collection of common animation curves. abstract class Curve { + /// Abstract const constructor. This constructor enables subclasses to provide + /// const constructors so that they can be used in const expressions. const Curve(); /// Returns the value of the curve at point [t]. diff --git a/packages/flutter/lib/src/animation/forces.dart b/packages/flutter/lib/src/animation/forces.dart index a3d6389f3c9..977bd401248 100644 --- a/packages/flutter/lib/src/animation/forces.dart +++ b/packages/flutter/lib/src/animation/forces.dart @@ -8,6 +8,8 @@ export 'package:newton/newton.dart' show SpringDescription; /// A factory for simulations. abstract class Force { + /// Abstract const constructor. This constructor enables subclasses to provide + /// const constructors so that they can be used in const expressions. const Force(); /// Creates a new physics simulation with the given initial conditions. diff --git a/packages/flutter/lib/src/animation/tween.dart b/packages/flutter/lib/src/animation/tween.dart index 405d35377e6..142eaf43cac 100644 --- a/packages/flutter/lib/src/animation/tween.dart +++ b/packages/flutter/lib/src/animation/tween.dart @@ -10,6 +10,8 @@ import 'curves.dart'; /// An object that can produce a value of type T given an [Animation] as input. abstract class Animatable { + /// Abstract const constructor. This constructor enables subclasses to provide + /// const constructors so that they can be used in const expressions. const Animatable(); /// The current value of this object for the given animation. diff --git a/packages/flutter/lib/src/http/mojo_client.dart b/packages/flutter/lib/src/http/mojo_client.dart index d4ddad6fb35..3665f4220a1 100644 --- a/packages/flutter/lib/src/http/mojo_client.dart +++ b/packages/flutter/lib/src/http/mojo_client.dart @@ -148,8 +148,7 @@ class MojoClient { mojo.UrlResponse response = (await loader.ptr.start(request)).response; ByteData data = await mojo.DataPipeDrainer.drainHandle(response.body); Uint8List bodyBytes = new Uint8List.view(data.buffer); - String bodyString = new String.fromCharCodes(bodyBytes); - return new Response(body: bodyString, bodyBytes: bodyBytes, statusCode: response.statusCode); + return new Response(bodyBytes: bodyBytes, statusCode: response.statusCode); } catch (e) { print("NetworkService unavailable $e"); return new Response(statusCode: 500); @@ -170,5 +169,6 @@ class MojoClient { return proxy; } + /// A handle to the [NetworkService] object used by [MojoClient]. static final mojo.NetworkServiceProxy networkService = _initNetworkService(); } diff --git a/packages/flutter/lib/src/http/response.dart b/packages/flutter/lib/src/http/response.dart index 1fdb117ef16..1d19900fdb4 100644 --- a/packages/flutter/lib/src/http/response.dart +++ b/packages/flutter/lib/src/http/response.dart @@ -6,8 +6,25 @@ import 'dart:typed_data'; /// An HTTP response where the entire response body is known in advance. class Response { - const Response({ this.body, this.bodyBytes, this.statusCode }); + /// Creates a [Response] object with the given fields. + /// + /// If [bodyBytes] is non-null, it is used to populate [body]. + Response({ + Uint8List bodyBytes, + this.statusCode + }) : body = bodyBytes != null ? new String.fromCharCodes(bodyBytes) : null, + bodyBytes = bodyBytes; + + /// The result of decoding [bodyBytes] using ISO-8859-1. + /// + /// If [bodyBytes] is null, this will also be null. final String body; + + /// The raw byte stream. final Uint8List bodyBytes; + + /// The HTTP result code. + /// + /// The code 500 is used when no status code could be obtained from the host. final int statusCode; } diff --git a/packages/flutter/lib/src/painting/box_painter.dart b/packages/flutter/lib/src/painting/box_painter.dart index 41ae481d36c..64e6e4f6e03 100644 --- a/packages/flutter/lib/src/painting/box_painter.dart +++ b/packages/flutter/lib/src/painting/box_painter.dart @@ -246,6 +246,8 @@ class BoxShadow { /// A 2D gradient. abstract class Gradient { + /// Abstract const constructor. This constructor enables subclasses to provide + /// const constructors so that they can be used in const expressions. const Gradient(); Shader createShader(Rect rect); } diff --git a/packages/flutter/lib/src/painting/decoration.dart b/packages/flutter/lib/src/painting/decoration.dart index c171aa6a52a..90984b09cb0 100644 --- a/packages/flutter/lib/src/painting/decoration.dart +++ b/packages/flutter/lib/src/painting/decoration.dart @@ -19,7 +19,8 @@ export 'edge_insets.dart' show EdgeInsets; /// shared between boxes; [BoxPainter] objects can cache resources to /// make painting on a particular surface faster. abstract class Decoration { - /// Abstract const constructor. + /// Abstract const constructor. This constructor enables subclasses to provide + /// const constructors so that they can be used in const expressions. const Decoration(); /// In checked mode, throws an exception if the object is not in a diff --git a/packages/flutter/lib/src/rendering/auto_layout.dart b/packages/flutter/lib/src/rendering/auto_layout.dart index fd8793f8b83..5579e95bc76 100644 --- a/packages/flutter/lib/src/rendering/auto_layout.dart +++ b/packages/flutter/lib/src/rendering/auto_layout.dart @@ -114,6 +114,8 @@ class AutoLayoutParentData extends ContainerBoxParentDataMixin { } abstract class AutoLayoutDelegate { + /// Abstract const constructor. This constructor enables subclasses to provide + /// const constructors so that they can be used in const expressions. const AutoLayoutDelegate(); List getConstraints(AutoLayoutRect parent); diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart index ae43f94befb..4bfd5ef53e0 100644 --- a/packages/flutter/lib/src/rendering/object.dart +++ b/packages/flutter/lib/src/rendering/object.dart @@ -356,6 +356,8 @@ abstract class RenderObjectPainter { /// Concrete layout models (such as box) will create concrete subclasses to /// communicate layout constraints between parents and children. abstract class Constraints { + /// Abstract const constructor. This constructor enables subclasses to provide + /// const constructors so that they can be used in const expressions. const Constraints(); /// Whether there is exactly one size possible given these constraints diff --git a/packages/flutter/lib/src/rendering/proxy_box.dart b/packages/flutter/lib/src/rendering/proxy_box.dart index 6deb7b87338..6eb9185ddc7 100644 --- a/packages/flutter/lib/src/rendering/proxy_box.dart +++ b/packages/flutter/lib/src/rendering/proxy_box.dart @@ -1300,6 +1300,8 @@ class RenderFractionalTranslation extends RenderProxyBox { } abstract class CustomPainter { + /// Abstract const constructor. This constructor enables subclasses to provide + /// const constructors so that they can be used in const expressions. const CustomPainter(); void paint(Canvas canvas, Size size);