decide method

Future<WebViewDownloadDecision> decide(
  1. WebViewDownloadRequest request, {
  2. Future<void>? cancelled,
})

Resolves one decision with a bounded wait and checks advertised actions. Platform implementations must cancel and report failures if this throws.

Implementation

Future<WebViewDownloadDecision> decide(
  WebViewDownloadRequest request, {
  Future<void>? cancelled,
}) async {
  final completion = Completer<WebViewDownloadDecision>();
  void fail(Object error, StackTrace stack) {
    if (!completion.isCompleted) completion.completeError(error, stack);
  }

  final timer = Timer(const Duration(seconds: 30), () {
    fail(
      TimeoutException('The download decision timed out.'),
      StackTrace.current,
    );
  });
  _watchDownloadDecision(
    Future<WebViewDownloadDecision>.sync(() => onDownloadRequest(request)),
    WeakReference(completion),
  );
  if (cancelled != null) {
    _watchDownloadCancellation(cancelled, WeakReference(completion));
  }
  final WebViewDownloadDecision decision;
  try {
    decision = await completion.future;
  } finally {
    timer.cancel();
  }
  if (!request.supportedActions.contains(decision.action)) {
    throw UnsupportedError('The requested download action is not supported.');
  }
  if (decision.action == WebViewDownloadAction.saveToFile &&
      (decision.path == null ||
          decision.path!.isEmpty ||
          decision.path!.contains('\u0000'))) {
    throw ArgumentError.value(
      decision.path,
      'path',
      'A non-empty file path is required.',
    );
  }
  return decision;
}