initServiceExtensions method Null safety

void initServiceExtensions(
  1. RegisterServiceExtensionCallback registerServiceExtensionCallback
)

Called to register service extensions.

See also:

Implementation

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

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

  SchedulerBinding.instance.addPersistentFrameCallback(_onFrameStart);

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

  _registerBoolServiceExtension(
    name: 'show',
    getter: () async => WidgetsApp.debugShowWidgetInspectorOverride,
    setter: (bool value) {
      if (WidgetsApp.debugShowWidgetInspectorOverride == value) {
        return Future<void>.value();
      }
      WidgetsApp.debugShowWidgetInspectorOverride = value;
      return forceRebuild();
    },
  );

  if (isWidgetCreationTracked()) {
    // Service extensions that are only supported if widget creation locations
    // are tracked.
    _registerBoolServiceExtension(
      name: 'trackRebuildDirtyWidgets',
      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;
        }
      },
    );

    _registerBoolServiceExtension(
      name: 'trackRepaintWidgets',
      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);
          }
          final RenderObject root = RendererBinding.instance.renderView;
          markTreeNeedsPaint(root);
        } else {
          debugOnProfilePaint = null;
        }
      },
    );
  }

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

  _registerServiceExtensionWithArg(
    name: 'getChildrenSummaryTree',
    callback: _getChildrenSummaryTree,
  );

  _registerServiceExtensionWithArg(
    name: 'getChildrenDetailsSubtree',
    callback: _getChildrenDetailsSubtree,
  );

  _registerObjectGroupServiceExtension(
    name: 'getRootWidget',
    callback: _getRootWidget,
  );
  _registerObjectGroupServiceExtension(
    name: 'getRootRenderObject',
    callback: _getRootRenderObject,
  );
  _registerObjectGroupServiceExtension(
    name: 'getRootWidgetSummaryTree',
    callback: _getRootWidgetSummaryTree,
  );
  registerServiceExtension(
    name: 'getDetailsSubtree',
    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,
        ),
      };
    },
  );
  _registerServiceExtensionWithArg(
    name: 'getSelectedRenderObject',
    callback: _getSelectedRenderObject,
  );
  _registerServiceExtensionWithArg(
    name: 'getSelectedWidget',
    callback: _getSelectedWidget,
  );
  _registerServiceExtensionWithArg(
    name: 'getSelectedSummaryWidget',
    callback: _getSelectedSummaryWidget,
  );

  _registerSignalServiceExtension(
    name: 'isWidgetCreationTracked',
    callback: isWidgetCreationTracked,
  );
  registerServiceExtension(
    name: 'screenshot',
    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);

      return <String, Object>{
        'result': base64.encoder.convert(Uint8List.view(byteData!.buffer)),
      };
    },
  );
}