captureScreenshot function

Future<ScreenshotResult> captureScreenshot(
  1. ScreenshotInput input, {
  2. Future<LifecycleQueryResult> lifecycleQuery()?,
})

Captures a screenshot of the running Flutter app.

Never throws (except AppDiedException which the dispatcher handles). All other error conditions are represented as ScreenshotFailed.

lifecycleQuery reports the app's lifecycle so a not-in-foreground (or VM-not-responding) warning can be added — the native capture shows whatever is on screen, which may be another app. Defaults to queryLifecycleState when a VM service URI is recorded in the session; pass a stub in tests. It runs concurrently with the capture and must not throw.

Implementation

Future<ScreenshotResult> captureScreenshot(
  ScreenshotInput input, {
  Future<LifecycleQueryResult> Function()? lifecycleQuery,
}) async {
  final warnings = <String>[];
  final output = input.output;

  // Read session state.
  final platformInfo = readPlatformInfo();
  final deviceId = readDevice();

  // Best-effort foreground check, started now so it overlaps the capture.
  final query = lifecycleQuery ?? (readVmUri() != null ? queryLifecycleState : null);
  final lifecycleFuture = query?.call();

  // Dispatch to the correct capture backend.
  final String? captureError;
  if (platformInfo != null) {
    captureError = await _dispatchScreenshot(
      platform: platformInfo.platform,
      emulator: platformInfo.emulator,
      deviceId: deviceId,
      output: output,
      warnings: warnings,
    );
  } else {
    captureError = await _legacyCapture(output, warnings);
  }

  if (lifecycleFuture != null) {
    final warning = lifecycleQueryWarning(await lifecycleFuture);
    if (warning != null) warnings.add(warning);
  }

  if (captureError != null) {
    return ScreenshotFailed(message: captureError, warnings: warnings);
  }

  final file = File(output);
  if (!file.existsSync()) {
    return ScreenshotFailed(
      message: 'Screenshot file not created',
      warnings: warnings,
    );
  }

  if (!input.fullResolution) {
    final resizeError = await _resizeToMaxDimension(output);
    if (resizeError != null) {
      return ScreenshotFailed(message: resizeError, warnings: warnings);
    }
  }

  final sizeBytes = file.lengthSync();
  return ScreenshotSaved(
    path: output,
    sizeBytes: sizeBytes,
    warnings: warnings,
  );
}