call method

Future<Object?> call(
  1. String service,
  2. String method, {
  3. Map<String, dynamic> params = const {},
  4. Object? fallback()?,
})

Calls a service method on the main app.

Returns the result, or throws:

If fallback is provided and the main app is disconnected, the fallback value is returned instead of throwing.

Implementation

Future<Object?> call(
  String service,
  String method, {
  Map<String, dynamic> params = const {},
  Object? Function()? fallback,
}) {
  // Fail fast if the main app is disconnected.
  if (!FloatyConnectionState.isMainAppConnected) {
    if (fallback != null) {
      return Future<Object?>.value(fallback());
    }
    return Future<Object?>.error(
      FloatyProxyDisconnectedException(service, method),
    );
  }

  final id = '${_nextId++}';
  final completer = Completer<Object?>();
  _pending[id] = completer;

  // Set up timeout.
  _timers[id] = Timer(timeout, () {
    _pending.remove(id);
    _timers.remove(id);
    if (!completer.isCompleted) {
      completer.completeError(
        FloatyProxyTimeoutException(service, method),
      );
    }
  });

  // Intentionally not awaited — the result arrives via the completer
  // when the host responds. The send itself is fire-and-forget.
  unawaited(
    FloatyChannel.sendSystem(_prefix, {
      'id': id,
      'type': 'request',
      'service': service,
      'method': method,
      'params': params,
    }),
  );

  return completer.future;
}