This commit is contained in:
parent
a6a1607888
commit
dc36195cb3
@ -93,9 +93,7 @@ abstract class BindingBase {
|
|||||||
/// Implementations of this method must call their superclass
|
/// Implementations of this method must call their superclass
|
||||||
/// implementation.
|
/// implementation.
|
||||||
///
|
///
|
||||||
/// Service extensions are only exposed when the observatory is
|
/// {@macro flutter.foundation.bindingBase.registerServiceExtension}
|
||||||
/// included in the build, which should only happen in checked mode
|
|
||||||
/// and in profile mode.
|
|
||||||
///
|
///
|
||||||
/// See also:
|
/// See also:
|
||||||
///
|
///
|
||||||
@ -104,18 +102,23 @@ abstract class BindingBase {
|
|||||||
@mustCallSuper
|
@mustCallSuper
|
||||||
void initServiceExtensions() {
|
void initServiceExtensions() {
|
||||||
assert(!_debugServiceExtensionsRegistered);
|
assert(!_debugServiceExtensionsRegistered);
|
||||||
|
|
||||||
|
assert(() {
|
||||||
registerSignalServiceExtension(
|
registerSignalServiceExtension(
|
||||||
name: 'reassemble',
|
name: 'reassemble',
|
||||||
callback: reassembleApplication,
|
callback: reassembleApplication,
|
||||||
);
|
);
|
||||||
|
return true;
|
||||||
|
}());
|
||||||
|
|
||||||
|
const bool isReleaseMode = bool.fromEnvironment('dart.vm.product');
|
||||||
|
if (!isReleaseMode) {
|
||||||
registerSignalServiceExtension(
|
registerSignalServiceExtension(
|
||||||
name: 'exit',
|
name: 'exit',
|
||||||
callback: _exitApplication,
|
callback: _exitApplication,
|
||||||
);
|
);
|
||||||
registerSignalServiceExtension(
|
}
|
||||||
name: 'frameworkPresent',
|
|
||||||
callback: () => Future<void>.value(),
|
|
||||||
);
|
|
||||||
assert(() {
|
assert(() {
|
||||||
registerServiceExtension(
|
registerServiceExtension(
|
||||||
name: 'platformOverride',
|
name: 'platformOverride',
|
||||||
@ -239,6 +242,8 @@ abstract class BindingBase {
|
|||||||
/// no value.
|
/// no value.
|
||||||
///
|
///
|
||||||
/// Calls the `callback` callback when the service extension is called.
|
/// Calls the `callback` callback when the service extension is called.
|
||||||
|
///
|
||||||
|
/// {@macro flutter.foundation.bindingBase.registerServiceExtension}
|
||||||
@protected
|
@protected
|
||||||
void registerSignalServiceExtension({
|
void registerSignalServiceExtension({
|
||||||
@required String name,
|
@required String name,
|
||||||
@ -267,6 +272,8 @@ abstract class BindingBase {
|
|||||||
///
|
///
|
||||||
/// Calls the `setter` callback with the new value when the
|
/// Calls the `setter` callback with the new value when the
|
||||||
/// service extension method is called with a new value.
|
/// service extension method is called with a new value.
|
||||||
|
///
|
||||||
|
/// {@macro flutter.foundation.bindingBase.registerServiceExtension}
|
||||||
@protected
|
@protected
|
||||||
void registerBoolServiceExtension({
|
void registerBoolServiceExtension({
|
||||||
@required String name,
|
@required String name,
|
||||||
@ -297,6 +304,8 @@ abstract class BindingBase {
|
|||||||
///
|
///
|
||||||
/// Calls the `setter` callback with the new value when the
|
/// Calls the `setter` callback with the new value when the
|
||||||
/// service extension method is called with a new value.
|
/// service extension method is called with a new value.
|
||||||
|
///
|
||||||
|
/// {@macro flutter.foundation.bindingBase.registerServiceExtension}
|
||||||
@protected
|
@protected
|
||||||
void registerNumericServiceExtension({
|
void registerNumericServiceExtension({
|
||||||
@required String name,
|
@required String name,
|
||||||
@ -326,6 +335,8 @@ abstract class BindingBase {
|
|||||||
///
|
///
|
||||||
/// Calls the `setter` callback with the new value when the
|
/// Calls the `setter` callback with the new value when the
|
||||||
/// service extension method is called with a new value.
|
/// service extension method is called with a new value.
|
||||||
|
///
|
||||||
|
/// {@macro flutter.foundation.bindingBase.registerServiceExtension}
|
||||||
@protected
|
@protected
|
||||||
void registerStringServiceExtension({
|
void registerStringServiceExtension({
|
||||||
@required String name,
|
@required String name,
|
||||||
@ -345,16 +356,51 @@ abstract class BindingBase {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Registers a service extension method with the given name (full
|
/// Registers a service extension method with the given name (full name
|
||||||
/// name "ext.flutter.name"). The given callback is called when the
|
/// "ext.flutter.name").
|
||||||
/// extension method is called. The callback must return a [Future]
|
///
|
||||||
/// that either eventually completes to a return value in the form
|
/// The given callback is called when the extension method is called. The
|
||||||
/// of a name/value map where the values can all be converted to
|
/// callback must return a [Future] that either eventually completes to a
|
||||||
/// JSON using `json.encode()` (see [JsonEncoder]), or fails. In case of failure, the
|
/// return value in the form of a name/value map where the values can all be
|
||||||
/// failure is reported to the remote caller and is dumped to the
|
/// converted to JSON using `json.encode()` (see [JsonEncoder]), or fails. In
|
||||||
/// logs.
|
/// case of failure, the failure is reported to the remote caller and is
|
||||||
|
/// dumped to the logs.
|
||||||
///
|
///
|
||||||
/// The returned map will be mutated.
|
/// The returned map will be mutated.
|
||||||
|
///
|
||||||
|
/// {@template flutter.foundation.bindingBase.registerServiceExtension}
|
||||||
|
/// A registered service extension can only be activated if the vm-service
|
||||||
|
/// is included in the build, which only happens in debug and profile mode.
|
||||||
|
/// Although a service extension cannot be used in release mode its code may
|
||||||
|
/// still be included in the Dart snapshot and blow up binary size if it is
|
||||||
|
/// not wrapped in a guard that allows the tree shaker to remove it (see
|
||||||
|
/// sample code below).
|
||||||
|
///
|
||||||
|
/// ## Sample Code
|
||||||
|
///
|
||||||
|
/// The following code registers a service extension that is only included in
|
||||||
|
/// debug builds:
|
||||||
|
///
|
||||||
|
/// ```dart
|
||||||
|
/// assert(() {
|
||||||
|
/// // Register your service extension here.
|
||||||
|
/// return true;
|
||||||
|
/// }());
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// A service extension registered with the following code snippet is
|
||||||
|
/// available in debug and profile mode:
|
||||||
|
///
|
||||||
|
/// ```dart
|
||||||
|
/// if (!const bool.fromEnvironment('dart.vm.product')) {
|
||||||
|
// // Register your service extension here.
|
||||||
|
// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Both guards ensure that Dart's tree shaker can remove the code for the
|
||||||
|
/// service extension in release builds.
|
||||||
|
/// {@endTemplate}
|
||||||
@protected
|
@protected
|
||||||
void registerServiceExtension({
|
void registerServiceExtension({
|
||||||
@required String name,
|
@required String name,
|
||||||
|
@ -51,7 +51,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Semanti
|
|||||||
super.initServiceExtensions();
|
super.initServiceExtensions();
|
||||||
|
|
||||||
assert(() {
|
assert(() {
|
||||||
// these service extensions only work in checked mode
|
// these service extensions only work in debug mode
|
||||||
registerBoolServiceExtension(
|
registerBoolServiceExtension(
|
||||||
name: 'debugPaint',
|
name: 'debugPaint',
|
||||||
getter: () async => debugPaintSizeEnabled,
|
getter: () async => debugPaintSizeEnabled,
|
||||||
@ -60,7 +60,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Semanti
|
|||||||
return Future<void>.value();
|
return Future<void>.value();
|
||||||
debugPaintSizeEnabled = value;
|
debugPaintSizeEnabled = value;
|
||||||
return _forceRepaint();
|
return _forceRepaint();
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
registerBoolServiceExtension(
|
registerBoolServiceExtension(
|
||||||
name: 'debugPaintBaselinesEnabled',
|
name: 'debugPaintBaselinesEnabled',
|
||||||
@ -70,7 +70,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Semanti
|
|||||||
return Future<void>.value();
|
return Future<void>.value();
|
||||||
debugPaintBaselinesEnabled = value;
|
debugPaintBaselinesEnabled = value;
|
||||||
return _forceRepaint();
|
return _forceRepaint();
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
registerBoolServiceExtension(
|
registerBoolServiceExtension(
|
||||||
name: 'repaintRainbow',
|
name: 'repaintRainbow',
|
||||||
@ -83,29 +83,44 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Semanti
|
|||||||
return Future<void>.value();
|
return Future<void>.value();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
registerSignalServiceExtension(
|
||||||
|
name: 'debugDumpLayerTree',
|
||||||
|
callback: () {
|
||||||
|
debugDumpLayerTree();
|
||||||
|
return debugPrintDone;
|
||||||
|
},
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}());
|
}());
|
||||||
|
|
||||||
|
const bool isReleaseMode = bool.fromEnvironment('dart.vm.product');
|
||||||
|
if (!isReleaseMode) {
|
||||||
|
// these service extensions work in debug or profile mode
|
||||||
registerSignalServiceExtension(
|
registerSignalServiceExtension(
|
||||||
name: 'debugDumpRenderTree',
|
name: 'debugDumpRenderTree',
|
||||||
callback: () { debugDumpRenderTree(); return debugPrintDone; }
|
callback: () {
|
||||||
);
|
debugDumpRenderTree();
|
||||||
|
return debugPrintDone;
|
||||||
registerSignalServiceExtension(
|
},
|
||||||
name: 'debugDumpLayerTree',
|
|
||||||
callback: () { debugDumpLayerTree(); return debugPrintDone; }
|
|
||||||
);
|
);
|
||||||
|
|
||||||
registerSignalServiceExtension(
|
registerSignalServiceExtension(
|
||||||
name: 'debugDumpSemanticsTreeInTraversalOrder',
|
name: 'debugDumpSemanticsTreeInTraversalOrder',
|
||||||
callback: () { debugDumpSemanticsTree(DebugSemanticsDumpOrder.traversalOrder); return debugPrintDone; }
|
callback: () {
|
||||||
|
debugDumpSemanticsTree(DebugSemanticsDumpOrder.traversalOrder);
|
||||||
|
return debugPrintDone;
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
registerSignalServiceExtension(
|
registerSignalServiceExtension(
|
||||||
name: 'debugDumpSemanticsTreeInInverseHitTestOrder',
|
name: 'debugDumpSemanticsTreeInInverseHitTestOrder',
|
||||||
callback: () { debugDumpSemanticsTree(DebugSemanticsDumpOrder.inverseHitTest); return debugPrintDone; }
|
callback: () {
|
||||||
|
debugDumpSemanticsTree(DebugSemanticsDumpOrder.inverseHitTest);
|
||||||
|
return debugPrintDone;
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a [RenderView] object to be the root of the
|
/// Creates a [RenderView] object to be the root of the
|
||||||
/// [RenderObject] rendering tree, and initializes it so that it
|
/// [RenderObject] rendering tree, and initializes it so that it
|
||||||
|
@ -203,14 +203,18 @@ mixin SchedulerBinding on BindingBase, ServicesBinding {
|
|||||||
@override
|
@override
|
||||||
void initServiceExtensions() {
|
void initServiceExtensions() {
|
||||||
super.initServiceExtensions();
|
super.initServiceExtensions();
|
||||||
|
|
||||||
|
const bool isReleaseMode = bool.fromEnvironment('dart.vm.product');
|
||||||
|
if (!isReleaseMode) {
|
||||||
registerNumericServiceExtension(
|
registerNumericServiceExtension(
|
||||||
name: 'timeDilation',
|
name: 'timeDilation',
|
||||||
getter: () async => timeDilation,
|
getter: () async => timeDilation,
|
||||||
setter: (double value) async {
|
setter: (double value) async {
|
||||||
timeDilation = value;
|
timeDilation = value;
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Whether the application is visible, and if so, whether it is currently
|
/// Whether the application is visible, and if so, whether it is currently
|
||||||
/// interactive.
|
/// interactive.
|
||||||
|
@ -86,6 +86,8 @@ mixin ServicesBinding on BindingBase {
|
|||||||
@override
|
@override
|
||||||
void initServiceExtensions() {
|
void initServiceExtensions() {
|
||||||
super.initServiceExtensions();
|
super.initServiceExtensions();
|
||||||
|
|
||||||
|
assert(() {
|
||||||
registerStringServiceExtension(
|
registerStringServiceExtension(
|
||||||
// ext.flutter.evict value=foo.png will cause foo.png to be evicted from
|
// 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.
|
// the rootBundle cache and cause the entire image cache to be cleared.
|
||||||
@ -95,8 +97,10 @@ mixin ServicesBinding on BindingBase {
|
|||||||
getter: () async => '',
|
getter: () async => '',
|
||||||
setter: (String value) async {
|
setter: (String value) async {
|
||||||
evict(value);
|
evict(value);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
return true;
|
||||||
|
}());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called in response to the `ext.flutter.evict` service extension.
|
/// Called in response to the `ext.flutter.evict` service extension.
|
||||||
|
@ -265,25 +265,30 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB
|
|||||||
void initServiceExtensions() {
|
void initServiceExtensions() {
|
||||||
super.initServiceExtensions();
|
super.initServiceExtensions();
|
||||||
|
|
||||||
|
const bool isReleaseMode = bool.fromEnvironment('dart.vm.product');
|
||||||
|
if (!isReleaseMode) {
|
||||||
registerSignalServiceExtension(
|
registerSignalServiceExtension(
|
||||||
name: 'debugDumpApp',
|
name: 'debugDumpApp',
|
||||||
callback: () {
|
callback: () {
|
||||||
debugDumpApp();
|
debugDumpApp();
|
||||||
return debugPrintDone;
|
return debugPrintDone;
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
registerBoolServiceExtension(
|
registerBoolServiceExtension(
|
||||||
name: 'showPerformanceOverlay',
|
name: 'showPerformanceOverlay',
|
||||||
getter: () => Future<bool>.value(WidgetsApp.showPerformanceOverlayOverride),
|
getter: () =>
|
||||||
|
Future<bool>.value(WidgetsApp.showPerformanceOverlayOverride),
|
||||||
setter: (bool value) {
|
setter: (bool value) {
|
||||||
if (WidgetsApp.showPerformanceOverlayOverride == value)
|
if (WidgetsApp.showPerformanceOverlayOverride == value)
|
||||||
return Future<void>.value();
|
return Future<void>.value();
|
||||||
WidgetsApp.showPerformanceOverlayOverride = value;
|
WidgetsApp.showPerformanceOverlayOverride = value;
|
||||||
return _forceRebuild();
|
return _forceRebuild();
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(() {
|
||||||
registerBoolServiceExtension(
|
registerBoolServiceExtension(
|
||||||
name: 'debugAllowBanner',
|
name: 'debugAllowBanner',
|
||||||
getter: () => Future<bool>.value(WidgetsApp.debugAllowBannerOverride),
|
getter: () => Future<bool>.value(WidgetsApp.debugAllowBannerOverride),
|
||||||
@ -292,10 +297,9 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB
|
|||||||
return Future<void>.value();
|
return Future<void>.value();
|
||||||
WidgetsApp.debugAllowBannerOverride = value;
|
WidgetsApp.debugAllowBannerOverride = value;
|
||||||
return _forceRebuild();
|
return _forceRebuild();
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
assert(() {
|
|
||||||
// Expose the ability to send Widget rebuilds as [Timeline] events.
|
// Expose the ability to send Widget rebuilds as [Timeline] events.
|
||||||
registerBoolServiceExtension(
|
registerBoolServiceExtension(
|
||||||
name: 'profileWidgetBuilds',
|
name: 'profileWidgetBuilds',
|
||||||
@ -303,12 +307,10 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB
|
|||||||
setter: (bool value) async {
|
setter: (bool value) async {
|
||||||
if (debugProfileBuildsEnabled != value)
|
if (debugProfileBuildsEnabled != value)
|
||||||
debugProfileBuildsEnabled = value;
|
debugProfileBuildsEnabled = value;
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
return true;
|
|
||||||
}());
|
|
||||||
|
|
||||||
// This service extension is deprecated and will be removed by 7/1/2018.
|
// This service extension is deprecated and will be removed by 12/1/2018.
|
||||||
// Use ext.flutter.inspector.show instead.
|
// Use ext.flutter.inspector.show instead.
|
||||||
registerBoolServiceExtension(
|
registerBoolServiceExtension(
|
||||||
name: 'debugWidgetInspector',
|
name: 'debugWidgetInspector',
|
||||||
@ -322,6 +324,9 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB
|
|||||||
);
|
);
|
||||||
|
|
||||||
WidgetInspectorService.instance.initServiceExtensions(registerServiceExtension);
|
WidgetInspectorService.instance.initServiceExtensions(registerServiceExtension);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}());
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _forceRebuild() {
|
Future<void> _forceRebuild() {
|
||||||
|
@ -917,13 +917,11 @@ mixin WidgetInspectorService {
|
|||||||
|
|
||||||
/// Called to register service extensions.
|
/// Called to register service extensions.
|
||||||
///
|
///
|
||||||
/// Service extensions are only exposed when the observatory is
|
|
||||||
/// included in the build, which should only happen in checked mode
|
|
||||||
/// and in profile mode.
|
|
||||||
///
|
|
||||||
/// See also:
|
/// See also:
|
||||||
///
|
///
|
||||||
/// * <https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#rpcs-requests-and-responses>
|
/// * <https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#rpcs-requests-and-responses>
|
||||||
|
/// * [BindingBase.initServiceExtensions], which explains when service
|
||||||
|
/// extensions can be used.
|
||||||
void initServiceExtensions(
|
void initServiceExtensions(
|
||||||
_RegisterServiceExtensionCallback registerServiceExtensionCallback) {
|
_RegisterServiceExtensionCallback registerServiceExtensionCallback) {
|
||||||
_registerServiceExtensionCallback = registerServiceExtensionCallback;
|
_registerServiceExtensionCallback = registerServiceExtensionCallback;
|
||||||
@ -1023,7 +1021,6 @@ mixin WidgetInspectorService {
|
|||||||
name: 'isWidgetCreationTracked',
|
name: 'isWidgetCreationTracked',
|
||||||
callback: isWidgetCreationTracked,
|
callback: isWidgetCreationTracked,
|
||||||
);
|
);
|
||||||
assert(() {
|
|
||||||
registerServiceExtension(
|
registerServiceExtension(
|
||||||
name: 'screenshot',
|
name: 'screenshot',
|
||||||
callback: (Map<String, String> parameters) async {
|
callback: (Map<String, String> parameters) async {
|
||||||
@ -1051,8 +1048,6 @@ mixin WidgetInspectorService {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return true;
|
|
||||||
}());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear all InspectorService object references.
|
/// Clear all InspectorService object references.
|
||||||
|
@ -359,13 +359,6 @@ void main() {
|
|||||||
expect(binding.extensions.containsKey('exit'), isTrue);
|
expect(binding.extensions.containsKey('exit'), isTrue);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Service extensions - frameworkPresent', () async {
|
|
||||||
Map<String, dynamic> result;
|
|
||||||
|
|
||||||
result = await binding.testExtension('frameworkPresent', <String, String>{});
|
|
||||||
expect(result, <String, String>{});
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Service extensions - platformOverride', () async {
|
test('Service extensions - platformOverride', () async {
|
||||||
Map<String, dynamic> result;
|
Map<String, dynamic> result;
|
||||||
|
|
||||||
@ -491,7 +484,6 @@ void main() {
|
|||||||
|
|
||||||
test('Service extensions - debugWidgetInspector', () async {
|
test('Service extensions - debugWidgetInspector', () async {
|
||||||
Map<String, dynamic> result;
|
Map<String, dynamic> result;
|
||||||
|
|
||||||
expect(binding.frameScheduled, isFalse);
|
expect(binding.frameScheduled, isFalse);
|
||||||
expect(WidgetsApp.debugShowWidgetInspectorOverride, false);
|
expect(WidgetsApp.debugShowWidgetInspectorOverride, false);
|
||||||
result = await binding.testExtension('debugWidgetInspector', <String, String>{});
|
result = await binding.testExtension('debugWidgetInspector', <String, String>{});
|
||||||
@ -541,7 +533,7 @@ void main() {
|
|||||||
|
|
||||||
// If you add a service extension... TEST IT! :-)
|
// If you add a service extension... TEST IT! :-)
|
||||||
// ...then increment this number.
|
// ...then increment this number.
|
||||||
expect(binding.extensions.length, 39);
|
expect(binding.extensions.length, 38);
|
||||||
|
|
||||||
expect(console, isEmpty);
|
expect(console, isEmpty);
|
||||||
debugPrint = debugPrintThrottled;
|
debugPrint = debugPrintThrottled;
|
||||||
|
@ -1296,10 +1296,6 @@ class Isolate extends ServiceObjectOwner {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> flutterFrameworkPresent() async {
|
|
||||||
return await invokeFlutterExtensionRpcRaw('ext.flutter.frameworkPresent') != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Map<String, dynamic>> uiWindowScheduleFrame() async {
|
Future<Map<String, dynamic>> uiWindowScheduleFrame() async {
|
||||||
return await invokeFlutterExtensionRpcRaw('ext.ui.window.scheduleFrame');
|
return await invokeFlutterExtensionRpcRaw('ext.ui.window.scheduleFrame');
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user