initServiceExtensions method

void initServiceExtensions(
  1. RegisterServiceExtensionCallback registerExtension
)

Called to register service extensions.

See also:

Implementation

void initServiceExtensions(RegisterServiceExtensionCallback registerExtension) {
  final FlutterExceptionHandler defaultExceptionHandler = FlutterError.presentError;

  if (isStructuredErrorsEnabled()) {
    FlutterError.presentError = _reportStructuredError;
  }
  assert(!_debugServiceExtensionsRegistered);
  assert(() {
    _debugServiceExtensionsRegistered = true;
    return true;
  }());

  SchedulerBinding.instance.addPersistentFrameCallback(_onFrameStart);

  _registerBoolServiceExtension(
    name: WidgetInspectorServiceExtensions.structuredErrors.name,
    getter: () async => FlutterError.presentError == _reportStructuredError,
    setter: (bool value) {
      FlutterError.presentError = value ? _reportStructuredError : defaultExceptionHandler;
      return Future<void>.value();
    },
    registerExtension: registerExtension,
  );

  _registerBoolServiceExtension(
    name: WidgetInspectorServiceExtensions.show.name,
    getter: () async => WidgetsBinding.instance.debugShowWidgetInspectorOverride,
    setter: (bool value) {
      if (WidgetsBinding.instance.debugShowWidgetInspectorOverride != value) {
        WidgetsBinding.instance.debugShowWidgetInspectorOverride = value;
      }
      return Future<void>.value();
    },
    registerExtension: registerExtension,
  );

  if (isWidgetCreationTracked()) {
    // Service extensions that are only supported if widget creation locations
    // are tracked.
    _registerBoolServiceExtension(
      name: WidgetInspectorServiceExtensions.trackRebuildDirtyWidgets.name,
      getter: () async => _trackRebuildDirtyWidgets,
      setter: (bool value) async {
        if (value == _trackRebuildDirtyWidgets) {
          return;
        }
        _rebuildStats.resetCounts();
        _trackRebuildDirtyWidgets = value;
        if (value) {
          assert(debugOnRebuildDirtyWidget == null);
          debugOnRebuildDirtyWidget = _onRebuildWidget;
          // Trigger a rebuild so there are baseline stats for rebuilds
          // performed by the app.
          await forceRebuild();
          return;
        } else {
          debugOnRebuildDirtyWidget = null;
          return;
        }
      },
      registerExtension: registerExtension,
    );

    _registerSignalServiceExtension(
      name: WidgetInspectorServiceExtensions.widgetLocationIdMap.name,
      callback: () {
        return _locationIdMapToJson();
      },
      registerExtension: registerExtension,
    );

    _registerBoolServiceExtension(
      name: WidgetInspectorServiceExtensions.trackRepaintWidgets.name,
      getter: () async => _trackRepaintWidgets,
      setter: (bool value) async {
        if (value == _trackRepaintWidgets) {
          return;
        }
        _repaintStats.resetCounts();
        _trackRepaintWidgets = value;
        if (value) {
          assert(debugOnProfilePaint == null);
          debugOnProfilePaint = _onPaint;
          // Trigger an immediate paint so the user has some baseline painting
          // stats to view.
          void markTreeNeedsPaint(RenderObject renderObject) {
            renderObject.markNeedsPaint();
            renderObject.visitChildren(markTreeNeedsPaint);
          }
          RendererBinding.instance.renderViews.forEach(markTreeNeedsPaint);
        } else {
          debugOnProfilePaint = null;
        }
      },
      registerExtension: registerExtension,
    );
  }

  _registerSignalServiceExtension(
    name: WidgetInspectorServiceExtensions.disposeAllGroups.name,
    callback: () async {
      disposeAllGroups();
      return null;
    },
    registerExtension: registerExtension,
  );
  _registerObjectGroupServiceExtension(
    name: WidgetInspectorServiceExtensions.disposeGroup.name,
    callback: (String name) async {
      disposeGroup(name);
      return null;
    },
    registerExtension: registerExtension,
  );
  _registerSignalServiceExtension(
    name: WidgetInspectorServiceExtensions.isWidgetTreeReady.name,
    callback: isWidgetTreeReady,
    registerExtension: registerExtension,
  );
  _registerServiceExtensionWithArg(
    name: WidgetInspectorServiceExtensions.disposeId.name,
    callback: (String? objectId, String objectGroup) async {
      disposeId(objectId, objectGroup);
      return null;
    },
    registerExtension: registerExtension,
  );
  _registerServiceExtensionVarArgs(
    name: WidgetInspectorServiceExtensions.setPubRootDirectories.name,
    callback: (List<String> args) async {
      setPubRootDirectories(args);
      return null;
    },
    registerExtension: registerExtension,
  );
  _registerServiceExtensionVarArgs(
    name: WidgetInspectorServiceExtensions.addPubRootDirectories.name,
    callback: (List<String> args) async {
      addPubRootDirectories(args);
      return null;
    },
    registerExtension: registerExtension,
  );
  _registerServiceExtensionVarArgs(
    name: WidgetInspectorServiceExtensions.removePubRootDirectories.name,
    callback: (List<String> args) async {
      removePubRootDirectories(args);
      return null;
    },
    registerExtension: registerExtension,
  );
  registerServiceExtension(
    name: WidgetInspectorServiceExtensions.getPubRootDirectories.name,
    callback: pubRootDirectories,
    registerExtension: registerExtension,
  );
  _registerServiceExtensionWithArg(
    name: WidgetInspectorServiceExtensions.setSelectionById.name,
    callback: setSelectionById,
    registerExtension: registerExtension,
  );
  _registerServiceExtensionWithArg(
    name: WidgetInspectorServiceExtensions.getParentChain.name,
    callback: _getParentChain,
    registerExtension: registerExtension,
  );
  _registerServiceExtensionWithArg(
    name: WidgetInspectorServiceExtensions.getProperties.name,
    callback: _getProperties,
    registerExtension: registerExtension,
  );
  _registerServiceExtensionWithArg(
    name: WidgetInspectorServiceExtensions.getChildren.name,
    callback: _getChildren,
    registerExtension: registerExtension,
  );

  _registerServiceExtensionWithArg(
    name: WidgetInspectorServiceExtensions.getChildrenSummaryTree.name,
    callback: _getChildrenSummaryTree,
    registerExtension: registerExtension,
  );

  _registerServiceExtensionWithArg(
    name: WidgetInspectorServiceExtensions.getChildrenDetailsSubtree.name,
    callback: _getChildrenDetailsSubtree,
    registerExtension: registerExtension,
  );

  _registerObjectGroupServiceExtension(
    name: WidgetInspectorServiceExtensions.getRootWidget.name,
    callback: _getRootWidget,
    registerExtension: registerExtension,
  );
  _registerObjectGroupServiceExtension(
    name: WidgetInspectorServiceExtensions.getRootWidgetSummaryTree.name,
    callback: _getRootWidgetSummaryTree,
    registerExtension: registerExtension,
  );
  registerServiceExtension(
    name: WidgetInspectorServiceExtensions.getRootWidgetSummaryTreeWithPreviews.name,
    callback: _getRootWidgetSummaryTreeWithPreviews,
    registerExtension: registerExtension,
  );
  registerServiceExtension(
    name: WidgetInspectorServiceExtensions.getRootWidgetTree.name,
    callback: _getRootWidgetTree,
    registerExtension: registerExtension,
  );
  registerServiceExtension(
    name: WidgetInspectorServiceExtensions.getDetailsSubtree.name,
    callback: (Map<String, String> parameters) async {
      assert(parameters.containsKey('objectGroup'));
      final String? subtreeDepth = parameters['subtreeDepth'];
      return <String, Object?>{
        'result': _getDetailsSubtree(
          parameters['arg'],
          parameters['objectGroup'],
          subtreeDepth != null ? int.parse(subtreeDepth) : 2,
        ),
      };
    },
    registerExtension: registerExtension,
  );
  _registerServiceExtensionWithArg(
    name: WidgetInspectorServiceExtensions.getSelectedWidget.name,
    callback: _getSelectedWidget,
    registerExtension: registerExtension,
  );
  _registerServiceExtensionWithArg(
    name: WidgetInspectorServiceExtensions.getSelectedSummaryWidget.name,
    callback: _getSelectedSummaryWidget,
    registerExtension: registerExtension,
  );

  _registerSignalServiceExtension(
    name: WidgetInspectorServiceExtensions.isWidgetCreationTracked.name,
    callback: isWidgetCreationTracked,
    registerExtension: registerExtension,
  );
  registerServiceExtension(
    name: WidgetInspectorServiceExtensions.screenshot.name,
    callback: (Map<String, String> parameters) async {
      assert(parameters.containsKey('id'));
      assert(parameters.containsKey('width'));
      assert(parameters.containsKey('height'));

      final ui.Image? image = await screenshot(
        toObject(parameters['id']),
        width: double.parse(parameters['width']!),
        height: double.parse(parameters['height']!),
        margin: parameters.containsKey('margin') ?
            double.parse(parameters['margin']!) : 0.0,
        maxPixelRatio: parameters.containsKey('maxPixelRatio') ?
            double.parse(parameters['maxPixelRatio']!) : 1.0,
        debugPaint: parameters['debugPaint'] == 'true',
      );
      if (image == null) {
        return <String, Object?>{'result': null};
      }
      final ByteData? byteData = await image.toByteData(format:ui.ImageByteFormat.png);
      image.dispose();

      return <String, Object>{
        'result': base64.encoder.convert(Uint8List.view(byteData!.buffer)),
      };
    },
    registerExtension: registerExtension,
  );
  registerServiceExtension(
    name: WidgetInspectorServiceExtensions.getLayoutExplorerNode.name,
    callback: _getLayoutExplorerNode,
    registerExtension: registerExtension,
  );
  registerServiceExtension(
    name: WidgetInspectorServiceExtensions.setFlexFit.name,
    callback: _setFlexFit,
    registerExtension: registerExtension,
  );
  registerServiceExtension(
    name: WidgetInspectorServiceExtensions.setFlexFactor.name,
    callback: _setFlexFactor,
    registerExtension: registerExtension,
  );
  registerServiceExtension(
    name: WidgetInspectorServiceExtensions.setFlexProperties.name,
    callback: _setFlexProperties,
    registerExtension: registerExtension,
  );
}