LCOV - code coverage report
Current view: top level - src/workers - parallel_http_download_worker.dart Coverage Total Hit
Test: lcov.info Lines: 100.0 % 17 17
Test Date: 2026-04-30 18:23:23 Functions: - 0 0

            Line data    Source code
       1              : import 'package:flutter/foundation.dart';
       2              : import '../worker.dart';
       3              : 
       4              : /// Parallel chunked HTTP download worker configuration.
       5              : ///
       6              : /// Splits a single file download into [numChunks] parallel byte-range
       7              : /// requests (HTTP/1.1 `Range` header, RFC 7233), downloads them
       8              : /// concurrently on the native side, then merges the parts into a single
       9              : /// output file — all without loading the file into memory.
      10              : ///
      11              : /// **When to use over [HttpDownloadWorker]:**
      12              : /// - Files larger than ~50 MB where parallel chunks give real speed-up.
      13              : /// - Servers that support `Accept-Ranges: bytes` (most CDNs do).
      14              : /// - When you want faster downloads on high-bandwidth connections.
      15              : ///
      16              : /// **Automatic fallback:** If the server does not advertise
      17              : /// `Accept-Ranges: bytes` or does not return a `Content-Length`, the
      18              : /// worker automatically falls back to a single sequential download
      19              : /// (identical to [HttpDownloadWorker]).
      20              : ///
      21              : /// ## Example
      22              : ///
      23              : /// ```dart
      24              : /// await NativeWorkManager.enqueue(
      25              : ///   taskId: 'big-video',
      26              : ///   trigger: TaskTrigger.oneTime(),
      27              : ///   worker: NativeWorker.parallelHttpDownload(
      28              : ///     url: 'https://cdn.example.com/movie.mp4',
      29              : ///     savePath: '/data/user/0/com.example/files/movie.mp4',
      30              : ///     numChunks: 4,           // default
      31              : ///     showNotification: true,
      32              : ///   ),
      33              : ///   constraints: Constraints.networkRequired,
      34              : /// );
      35              : /// ```
      36              : ///
      37              : /// ## Progress events
      38              : ///
      39              : /// Progress is reported as aggregate bytes across all chunks, so the
      40              : /// [TaskProgress.progress] field rises smoothly from 0 to 100 even
      41              : /// when chunks finish out of order.
      42              : ///
      43              : /// ## Resume support
      44              : ///
      45              : /// Each chunk is saved to `savePath.partN` temporarily.  If the task is
      46              : /// interrupted, a subsequent enqueue will pick up any completed parts and
      47              : /// only re-download missing or incomplete chunks.
      48              : @immutable
      49              : final class ParallelHttpDownloadWorker extends Worker {
      50            1 :   const ParallelHttpDownloadWorker({
      51              :     required this.url,
      52              :     required this.savePath,
      53              :     this.numChunks = 4,
      54              :     this.headers = const {},
      55              :     this.timeout = const Duration(minutes: 10),
      56              :     this.expectedChecksum,
      57              :     this.checksumAlgorithm = 'SHA-256',
      58              :     this.showNotification = false,
      59              :     this.notificationTitle,
      60              :     this.notificationBody,
      61              :     this.skipExisting = false,
      62            3 :   }) : assert(numChunks >= 1 && numChunks <= 16,
      63              :             'numChunks must be between 1 and 16');
      64              : 
      65              :   /// The URL to download from.
      66              :   final String url;
      67              : 
      68              :   /// Absolute path where the merged file will be saved.
      69              :   final String savePath;
      70              : 
      71              :   /// Number of parallel byte-range chunks (1–16, default 4).
      72              :   ///
      73              :   /// A value of 1 is equivalent to a sequential download but still goes
      74              :   /// through the parallel code path.  Values above 8 rarely improve
      75              :   /// throughput and increase connection overhead.
      76              :   final int numChunks;
      77              : 
      78              :   /// Optional HTTP headers sent with every chunk request.
      79              :   final Map<String, String> headers;
      80              : 
      81              :   /// Per-chunk request timeout (default: 10 minutes).
      82              :   ///
      83              :   /// Each chunk has its own independent timeout counter.
      84              :   final Duration timeout;
      85              : 
      86              :   /// Expected checksum for the merged file (optional).
      87              :   ///
      88              :   /// Verified after all chunks are merged. Download fails if checksums
      89              :   /// do not match.
      90              :   final String? expectedChecksum;
      91              : 
      92              :   /// Hashing algorithm for checksum verification (default: `'SHA-256'`).
      93              :   ///
      94              :   /// Supported: `'MD5'`, `'SHA-1'`, `'SHA-256'`, `'SHA-512'`.
      95              :   final String checksumAlgorithm;
      96              : 
      97              :   /// Show a system notification with aggregate download progress.
      98              :   final bool showNotification;
      99              : 
     100              :   /// Title for the progress notification.
     101              :   ///
     102              :   /// Defaults to the file name derived from [url].
     103              :   final String? notificationTitle;
     104              : 
     105              :   /// Body text for the progress notification.
     106              :   final String? notificationBody;
     107              : 
     108              :   /// Skip the download if [savePath] already exists on disk.
     109              :   ///
     110              :   /// Same semantics as [HttpDownloadWorker.skipExisting].
     111              :   /// Default: `false`
     112              :   final bool skipExisting;
     113              : 
     114            1 :   @override
     115              :   String get workerClassName => 'ParallelHttpDownloadWorker';
     116              : 
     117            1 :   @override
     118            1 :   Map<String, dynamic> toMap() => {
     119            1 :         'workerType': 'parallelHttpDownload',
     120            2 :         'url': url,
     121            2 :         'savePath': savePath,
     122            2 :         'numChunks': numChunks,
     123            2 :         'headers': headers,
     124            3 :         'timeoutMs': timeout.inMilliseconds,
     125            1 :         if (expectedChecksum != null) 'expectedChecksum': expectedChecksum,
     126            2 :         'checksumAlgorithm': checksumAlgorithm,
     127            2 :         'skipExisting': skipExisting,
     128            2 :         'showNotification': showNotification,
     129            1 :         if (notificationTitle != null) 'notificationTitle': notificationTitle,
     130            1 :         if (notificationBody != null) 'notificationBody': notificationBody,
     131              :       };
     132              : }
        

Generated by: LCOV version 2.4-0