downloadModel method

  1. @override
Stream<ModelDownloadStatus> downloadModel()
override

Asks the OS / browser to download the model, reporting progress.

The stream completes when the model is ready or the download failed.

Implementation

@override
Stream<ModelDownloadStatus> downloadModel() {
  final controller = StreamController<ModelDownloadStatus>();
  () async {
    try {
      final raw = await _rawAvailability();
      if (raw == 'available') {
        controller.add(
          const ModelDownloadStatus(
            status: ModelFeatureStatus.available,
            progress: 1,
          ),
        );
        return;
      }
      if (raw == 'missing' || raw == 'unavailable') {
        controller.add(
          const ModelDownloadStatus(
            status: ModelFeatureStatus.unavailable,
            errorMessage: 'The built-in model is not supported here.',
          ),
        );
        return;
      }
      if (raw == 'downloadable' && !_userActivationActive()) {
        controller.addError(
          const OnDeviceAiUserActivationRequiredException(
            'Downloading the built-in model needs a user gesture. Call '
            'ensureReady() from a click or tap handler.',
          ),
        );
        return;
      }
      controller.add(
        const ModelDownloadStatus(
          status: ModelFeatureStatus.downloading,
          progress: 0,
        ),
      );
      final session = await _create(
        null,
        null,
        onProgress: (p) => controller.add(
          ModelDownloadStatus(
            status: ModelFeatureStatus.downloading,
            progress: p,
          ),
        ),
      );
      session.callMethod<JSAny?>('destroy'.toJS);
      controller.add(
        const ModelDownloadStatus(
          status: ModelFeatureStatus.available,
          progress: 1,
        ),
      );
    } catch (e) {
      controller.add(
        ModelDownloadStatus(
          status: ModelFeatureStatus.unavailable,
          errorMessage: _describe(e),
        ),
      );
    } finally {
      await controller.close();
    }
  }();
  return controller.stream;
}