captureScreenshot method

Future<CockpitCaptureResult> captureScreenshot(
  1. CockpitScreenshotRequest request, {
  2. CockpitCaptureProfile? profile,
  3. bool? allowFallback,
})

Implementation

Future<CockpitCaptureResult> captureScreenshot(
  CockpitScreenshotRequest request, {
  CockpitCaptureProfile? profile,
  bool? allowFallback,
}) async {
  final effectiveProfile =
      profile ?? request.profile ?? _defaultProfileFor(request);
  final effectiveAllowFallback = allowFallback ?? request.allowsFallback;
  final effectiveRequest = request.snapshotOptions == null
      ? request.copyWith(
          snapshotOptions: _defaultSnapshotOptionsFor(request.reason),
        )
      : request;
  final surfaceState = _requireSurfaceState();

  if (effectiveRequest.reason == CockpitScreenshotReason.acceptance) {
    try {
      await waitForUiIdle();
    } on Object {
      // Idle observation improves capture stability but is not a prerequisite.
    }
  }

  final snapshotData = effectiveRequest.includeSnapshot
      ? surfaceState.snapshot(
          options:
              effectiveRequest.snapshotOptions ??
              _defaultSnapshotOptionsFor(effectiveRequest.reason),
        )
      : null;

  final prefersNativeCapture = cockpitCaptureProfilePrefersNative(
    effectiveProfile,
    isWeb: kIsWeb,
  );
  if (prefersNativeCapture) {
    final nativeCaptureAvailable = await FlutterCockpit.binding
        .queryNativeCaptureAvailability();
    if (!nativeCaptureAvailable) {
      if (!effectiveAllowFallback) {
        throw PlatformException(
          code: 'nativeCaptureUnavailable',
          message: 'Native screenshot capture is unavailable.',
        );
      }
      final screenshot = await surfaceState.captureScreenshot(
        effectiveRequest,
      );
      return CockpitCaptureResult(
        screenshot: screenshot,
        requestedProfile: effectiveProfile,
        resolvedCaptureKind: CockpitCaptureKind.flutterView,
        usedFallback: true,
        degradationReason: 'nativeCaptureUnavailable',
      );
    }

    try {
      final screenshot = await FlutterCockpit.binding.nativeCapture.capture(
        request: effectiveRequest,
        profile: effectiveProfile,
        snapshot: snapshotData,
      );
      return CockpitCaptureResult(
        screenshot: screenshot,
        requestedProfile: effectiveProfile,
        resolvedCaptureKind: CockpitCaptureKind.appNative,
      );
    } on Object catch (error, stackTrace) {
      if (!effectiveAllowFallback) {
        rethrow;
      }

      final CockpitCapturedScreenshot screenshot;
      try {
        screenshot = await surfaceState.captureScreenshot(effectiveRequest);
      } on Object catch (fallbackError, fallbackStackTrace) {
        Error.throwWithStackTrace(
          CockpitCaptureFallbackException(
            primaryError: error,
            primaryStackTrace: stackTrace,
            fallbackError: fallbackError,
            fallbackStackTrace: fallbackStackTrace,
          ),
          stackTrace,
        );
      }
      return CockpitCaptureResult(
        screenshot: screenshot,
        requestedProfile: effectiveProfile,
        resolvedCaptureKind: CockpitCaptureKind.flutterView,
        usedFallback: true,
        degradationReason: _captureFailureReason(error),
      );
    }
  }

  final screenshot = await surfaceState.captureScreenshot(effectiveRequest);
  return CockpitCaptureResult(
    screenshot: screenshot,
    requestedProfile: effectiveProfile,
    resolvedCaptureKind: CockpitCaptureKind.flutterView,
  );
}