LCOV - code coverage report
Current view: top level - lib/src/utils - native_implementations.dart (source / functions) Coverage Total Hit
Test: merged.info Lines: 24.5 % 49 12
Test Date: 2025-01-14 13:39:53 Functions: - 0 0

            Line data    Source code
       1              : import 'dart:async';
       2              : import 'dart:typed_data';
       3              : 
       4              : import 'package:matrix/encryption.dart';
       5              : import 'package:matrix/matrix.dart';
       6              : import 'package:matrix/src/utils/compute_callback.dart';
       7              : 
       8              : /// provides native implementations for demanding arithmetic operations
       9              : /// in order to prevent the UI from blocking
      10              : ///
      11              : /// possible implementations might be:
      12              : /// - native code
      13              : /// - another Dart isolate
      14              : /// - a web worker
      15              : /// - a dummy implementations
      16              : ///
      17              : /// Rules for extension (important for [noSuchMethod] implementations)
      18              : /// - always only accept exactly *one* positioned argument
      19              : /// - catch the corresponding case in [NativeImplementations.noSuchMethod]
      20              : /// - always write a dummy implementations
      21              : abstract class NativeImplementations {
      22           80 :   const NativeImplementations();
      23              : 
      24              :   /// a dummy implementation executing all calls in the same thread causing
      25              :   /// the UI to likely freeze
      26              :   static const dummy = NativeImplementationsDummy();
      27              : 
      28              :   FutureOr<RoomKeys> generateUploadKeys(
      29              :     GenerateUploadKeysArgs args, {
      30              :     bool retryInDummy = true,
      31              :   });
      32              : 
      33              :   FutureOr<Uint8List> keyFromPassphrase(
      34              :     KeyFromPassphraseArgs args, {
      35              :     bool retryInDummy = true,
      36              :   });
      37              : 
      38              :   FutureOr<Uint8List?> decryptFile(
      39              :     EncryptedFile file, {
      40              :     bool retryInDummy = true,
      41              :   });
      42              : 
      43              :   FutureOr<MatrixImageFileResizedResponse?> shrinkImage(
      44              :     MatrixImageFileResizeArguments args, {
      45              :     bool retryInDummy = false,
      46              :   });
      47              : 
      48              :   FutureOr<MatrixImageFileResizedResponse?> calcImageMetadata(
      49              :     Uint8List bytes, {
      50              :     bool retryInDummy = false,
      51              :   });
      52              : 
      53              :   /// this implementation will catch any non-implemented method
      54            0 :   @override
      55              :   dynamic noSuchMethod(Invocation invocation) {
      56            0 :     final dynamic argument = invocation.positionalArguments.single;
      57            0 :     final memberName = invocation.memberName.toString().split('"')[1];
      58              : 
      59            0 :     Logs().d(
      60              :       'Missing implementations of Client.nativeImplementations.$memberName. '
      61              :       'You should consider implementing it. '
      62              :       'Fallback from NativeImplementations.dummy used.',
      63              :     );
      64              :     switch (memberName) {
      65              :       // we need to pass the futures right through or we will run into type errors later!
      66            0 :       case 'generateUploadKeys':
      67              :         // ignore: discarded_futures
      68            0 :         return dummy.generateUploadKeys(argument);
      69            0 :       case 'keyFromPassphrase':
      70              :         // ignore: discarded_futures
      71            0 :         return dummy.keyFromPassphrase(argument);
      72            0 :       case 'decryptFile':
      73              :         // ignore: discarded_futures
      74            0 :         return dummy.decryptFile(argument);
      75            0 :       case 'shrinkImage':
      76            0 :         return dummy.shrinkImage(argument);
      77            0 :       case 'calcImageMetadata':
      78            0 :         return dummy.calcImageMetadata(argument);
      79              :       default:
      80            0 :         return super.noSuchMethod(invocation);
      81              :     }
      82              :   }
      83              : }
      84              : 
      85              : class NativeImplementationsDummy extends NativeImplementations {
      86           80 :   const NativeImplementationsDummy();
      87              : 
      88            1 :   @override
      89              :   Future<Uint8List?> decryptFile(
      90              :     EncryptedFile file, {
      91              :     bool retryInDummy = true,
      92              :   }) {
      93            1 :     return decryptFileImplementation(file);
      94              :   }
      95              : 
      96            4 :   @override
      97              :   Future<RoomKeys> generateUploadKeys(
      98              :     GenerateUploadKeysArgs args, {
      99              :     bool retryInDummy = true,
     100              :   }) async {
     101            4 :     return generateUploadKeysImplementation(args);
     102              :   }
     103              : 
     104            2 :   @override
     105              :   Future<Uint8List> keyFromPassphrase(
     106              :     KeyFromPassphraseArgs args, {
     107              :     bool retryInDummy = true,
     108              :   }) {
     109            2 :     return generateKeyFromPassphrase(args);
     110              :   }
     111              : 
     112            3 :   @override
     113              :   MatrixImageFileResizedResponse? shrinkImage(
     114              :     MatrixImageFileResizeArguments args, {
     115              :     bool retryInDummy = false,
     116              :   }) {
     117            3 :     return MatrixImageFile.resizeImplementation(args);
     118              :   }
     119              : 
     120            2 :   @override
     121              :   MatrixImageFileResizedResponse? calcImageMetadata(
     122              :     Uint8List bytes, {
     123              :     bool retryInDummy = false,
     124              :   }) {
     125            2 :     return MatrixImageFile.calcMetadataImplementation(bytes);
     126              :   }
     127              : }
     128              : 
     129              : /// a [NativeImplementations] based on Flutter's `compute` function
     130              : ///
     131              : /// this implementations simply wraps the given [compute] function around
     132              : /// the implementation of [NativeImplementations.dummy]
     133              : class NativeImplementationsIsolate extends NativeImplementations {
     134              :   /// pass by Flutter's compute function here
     135              :   final ComputeCallback compute;
     136              : 
     137            0 :   NativeImplementationsIsolate(this.compute);
     138              : 
     139              :   /// creates a [NativeImplementationsIsolate] based on a [ComputeRunner] as
     140              :   // ignore: deprecated_member_use_from_same_package
     141              :   /// known from [Client.runInBackground]
     142            0 :   factory NativeImplementationsIsolate.fromRunInBackground(
     143              :     ComputeRunner runInBackground,
     144              :   ) {
     145            0 :     return NativeImplementationsIsolate(
     146            0 :       computeCallbackFromRunInBackground(runInBackground),
     147              :     );
     148              :   }
     149              : 
     150            0 :   Future<T> runInBackground<T, U>(
     151              :     FutureOr<T> Function(U arg) function,
     152              :     U arg,
     153              :   ) async {
     154            0 :     final compute = this.compute;
     155            0 :     return await compute(function, arg);
     156              :   }
     157              : 
     158            0 :   @override
     159              :   Future<Uint8List?> decryptFile(
     160              :     EncryptedFile file, {
     161              :     bool retryInDummy = true,
     162              :   }) {
     163            0 :     return runInBackground<Uint8List?, EncryptedFile>(
     164            0 :       NativeImplementations.dummy.decryptFile,
     165              :       file,
     166              :     );
     167              :   }
     168              : 
     169            0 :   @override
     170              :   Future<RoomKeys> generateUploadKeys(
     171              :     GenerateUploadKeysArgs args, {
     172              :     bool retryInDummy = true,
     173              :   }) async {
     174            0 :     return runInBackground<RoomKeys, GenerateUploadKeysArgs>(
     175            0 :       NativeImplementations.dummy.generateUploadKeys,
     176              :       args,
     177              :     );
     178              :   }
     179              : 
     180            0 :   @override
     181              :   Future<Uint8List> keyFromPassphrase(
     182              :     KeyFromPassphraseArgs args, {
     183              :     bool retryInDummy = true,
     184              :   }) {
     185            0 :     return runInBackground<Uint8List, KeyFromPassphraseArgs>(
     186            0 :       NativeImplementations.dummy.keyFromPassphrase,
     187              :       args,
     188              :     );
     189              :   }
     190              : 
     191            0 :   @override
     192              :   Future<MatrixImageFileResizedResponse?> shrinkImage(
     193              :     MatrixImageFileResizeArguments args, {
     194              :     bool retryInDummy = false,
     195              :   }) {
     196            0 :     return runInBackground<MatrixImageFileResizedResponse?,
     197              :         MatrixImageFileResizeArguments>(
     198            0 :       NativeImplementations.dummy.shrinkImage,
     199              :       args,
     200              :     );
     201              :   }
     202              : 
     203            0 :   @override
     204              :   FutureOr<MatrixImageFileResizedResponse?> calcImageMetadata(
     205              :     Uint8List bytes, {
     206              :     bool retryInDummy = false,
     207              :   }) {
     208            0 :     return runInBackground<MatrixImageFileResizedResponse?, Uint8List>(
     209            0 :       NativeImplementations.dummy.calcImageMetadata,
     210              :       bytes,
     211              :     );
     212              :   }
     213              : }
        

Generated by: LCOV version 2.0-1