LCOV - code coverage report
Current view: top level - lib/src/utils - native_implementations.dart (source / functions) Hit Total Coverage
Test: merged.info Lines: 12 49 24.5 %
Date: 2024-09-30 15:57:20 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          82 :   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          82 :   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           0 :     return NativeImplementationsIsolate(
     145           0 :       computeCallbackFromRunInBackground(runInBackground),
     146             :     );
     147             :   }
     148             : 
     149           0 :   Future<T> runInBackground<T, U>(
     150             :       FutureOr<T> Function(U arg) function, U arg) async {
     151           0 :     final compute = this.compute;
     152           0 :     return await compute(function, arg);
     153             :   }
     154             : 
     155           0 :   @override
     156             :   Future<Uint8List?> decryptFile(
     157             :     EncryptedFile file, {
     158             :     bool retryInDummy = true,
     159             :   }) {
     160           0 :     return runInBackground<Uint8List?, EncryptedFile>(
     161           0 :       NativeImplementations.dummy.decryptFile,
     162             :       file,
     163             :     );
     164             :   }
     165             : 
     166           0 :   @override
     167             :   Future<RoomKeys> generateUploadKeys(
     168             :     GenerateUploadKeysArgs args, {
     169             :     bool retryInDummy = true,
     170             :   }) async {
     171           0 :     return runInBackground<RoomKeys, GenerateUploadKeysArgs>(
     172           0 :       NativeImplementations.dummy.generateUploadKeys,
     173             :       args,
     174             :     );
     175             :   }
     176             : 
     177           0 :   @override
     178             :   Future<Uint8List> keyFromPassphrase(
     179             :     KeyFromPassphraseArgs args, {
     180             :     bool retryInDummy = true,
     181             :   }) {
     182           0 :     return runInBackground<Uint8List, KeyFromPassphraseArgs>(
     183           0 :       NativeImplementations.dummy.keyFromPassphrase,
     184             :       args,
     185             :     );
     186             :   }
     187             : 
     188           0 :   @override
     189             :   Future<MatrixImageFileResizedResponse?> shrinkImage(
     190             :     MatrixImageFileResizeArguments args, {
     191             :     bool retryInDummy = false,
     192             :   }) {
     193           0 :     return runInBackground<MatrixImageFileResizedResponse?,
     194             :         MatrixImageFileResizeArguments>(
     195           0 :       NativeImplementations.dummy.shrinkImage,
     196             :       args,
     197             :     );
     198             :   }
     199             : 
     200           0 :   @override
     201             :   FutureOr<MatrixImageFileResizedResponse?> calcImageMetadata(
     202             :     Uint8List bytes, {
     203             :     bool retryInDummy = false,
     204             :   }) {
     205           0 :     return runInBackground<MatrixImageFileResizedResponse?, Uint8List>(
     206           0 :       NativeImplementations.dummy.calcImageMetadata,
     207             :       bytes,
     208             :     );
     209             :   }
     210             : }

Generated by: LCOV version 1.14