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-11-12 07:37:08 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             :   ) {
     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 1.14