initServiceExtensions method
Called when the binding is initialized, to register service extensions.
Bindings that want to expose service extensions should overload this method to register them using calls to registerSignalServiceExtension, registerBoolServiceExtension, registerNumericServiceExtension, and registerServiceExtension (in increasing order of complexity).
Implementations of this method must call their superclass implementation.
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).
void myRegistrationFunction() {
assert(() {
// Register your service extension here.
return true;
}());
}
void myOtherRegistrationFunction() {
// kReleaseMode is defined in the 'flutter/foundation.dart' package.
if (!kReleaseMode) {
// Register your service extension here.
}
}
Both guards ensure that Dart's tree shaker can remove the code for the service extension in release builds.
See also:
Implementation
@override
void initServiceExtensions() {
super.initServiceExtensions();
assert(() {
// these service extensions only work in debug mode
registerBoolServiceExtension(
name: RenderingServiceExtensions.invertOversizedImages.name,
getter: () async => debugInvertOversizedImages,
setter: (bool value) async {
if (debugInvertOversizedImages != value) {
debugInvertOversizedImages = value;
return _forceRepaint();
}
return Future<void>.value();
},
);
registerBoolServiceExtension(
name: RenderingServiceExtensions.debugPaint.name,
getter: () async => debugPaintSizeEnabled,
setter: (bool value) {
if (debugPaintSizeEnabled == value) {
return Future<void>.value();
}
debugPaintSizeEnabled = value;
return _forceRepaint();
},
);
registerBoolServiceExtension(
name: RenderingServiceExtensions.debugPaintBaselinesEnabled.name,
getter: () async => debugPaintBaselinesEnabled,
setter: (bool value) {
if (debugPaintBaselinesEnabled == value) {
return Future<void>.value();
}
debugPaintBaselinesEnabled = value;
return _forceRepaint();
},
);
registerBoolServiceExtension(
name: RenderingServiceExtensions.repaintRainbow.name,
getter: () async => debugRepaintRainbowEnabled,
setter: (bool value) {
final bool repaint = debugRepaintRainbowEnabled && !value;
debugRepaintRainbowEnabled = value;
if (repaint) {
return _forceRepaint();
}
return Future<void>.value();
},
);
registerServiceExtension(
name: RenderingServiceExtensions.debugDumpLayerTree.name,
callback: (Map<String, String> parameters) async {
return <String, Object>{
'data': _debugCollectLayerTrees(),
};
},
);
registerBoolServiceExtension(
name: RenderingServiceExtensions.debugDisableClipLayers.name,
getter: () async => debugDisableClipLayers,
setter: (bool value) {
if (debugDisableClipLayers == value) {
return Future<void>.value();
}
debugDisableClipLayers = value;
return _forceRepaint();
},
);
registerBoolServiceExtension(
name: RenderingServiceExtensions.debugDisablePhysicalShapeLayers.name,
getter: () async => debugDisablePhysicalShapeLayers,
setter: (bool value) {
if (debugDisablePhysicalShapeLayers == value) {
return Future<void>.value();
}
debugDisablePhysicalShapeLayers = value;
return _forceRepaint();
},
);
registerBoolServiceExtension(
name: RenderingServiceExtensions.debugDisableOpacityLayers.name,
getter: () async => debugDisableOpacityLayers,
setter: (bool value) {
if (debugDisableOpacityLayers == value) {
return Future<void>.value();
}
debugDisableOpacityLayers = value;
return _forceRepaint();
},
);
return true;
}());
if (!kReleaseMode) {
// these service extensions work in debug or profile mode
registerServiceExtension(
name: RenderingServiceExtensions.debugDumpRenderTree.name,
callback: (Map<String, String> parameters) async {
return <String, Object>{
'data': _debugCollectRenderTrees(),
};
},
);
registerServiceExtension(
name: RenderingServiceExtensions.debugDumpSemanticsTreeInTraversalOrder.name,
callback: (Map<String, String> parameters) async {
return <String, Object>{
'data': _debugCollectSemanticsTrees(DebugSemanticsDumpOrder.traversalOrder),
};
},
);
registerServiceExtension(
name: RenderingServiceExtensions.debugDumpSemanticsTreeInInverseHitTestOrder.name,
callback: (Map<String, String> parameters) async {
return <String, Object>{
'data': _debugCollectSemanticsTrees(DebugSemanticsDumpOrder.inverseHitTest),
};
},
);
registerBoolServiceExtension(
name: RenderingServiceExtensions.profileRenderObjectPaints.name,
getter: () async => debugProfilePaintsEnabled,
setter: (bool value) async {
if (debugProfilePaintsEnabled != value) {
debugProfilePaintsEnabled = value;
}
},
);
registerBoolServiceExtension(
name: RenderingServiceExtensions.profileRenderObjectLayouts.name,
getter: () async => debugProfileLayoutsEnabled,
setter: (bool value) async {
if (debugProfileLayoutsEnabled != value) {
debugProfileLayoutsEnabled = value;
}
},
);
}
}