From 209035ffbd023bd5549dafd79795012ecf496da9 Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Wed, 21 Jul 2021 11:51:08 +0200 Subject: [PATCH] refactor: Use official Dart isolates The isolates package is discontinued and not compatible with the newest Dart version. dart:isolate is not an option because importing this library makes it impossible to run the matrix SDK on dart web native. It just won't build. So we now just depend on that the flutter app pass through the compute method. --- lib/encryption/key_manager.dart | 3 +- lib/encryption/ssss.dart | 35 ++++++++++---------- lib/src/client.dart | 14 ++++++++ lib/src/event.dart | 3 +- lib/src/utils/run_in_background.dart | 49 ---------------------------- pubspec.yaml | 1 - 6 files changed, 34 insertions(+), 71 deletions(-) delete mode 100644 lib/src/utils/run_in_background.dart diff --git a/lib/encryption/key_manager.dart b/lib/encryption/key_manager.dart index ce39c2a0..fd93e9cd 100644 --- a/lib/encryption/key_manager.dart +++ b/lib/encryption/key_manager.dart @@ -25,7 +25,6 @@ import './encryption.dart'; import './utils/outbound_group_session.dart'; import './utils/session_key.dart'; import '../matrix.dart'; -import '../src/utils/run_in_background.dart'; import '../src/utils/run_in_root.dart'; const megolmKey = EventTypes.MegolmBackup; @@ -734,7 +733,7 @@ class KeyManager { } } final roomKeys = - await runInBackground( + await client.runInBackground( _generateUploadKeys, args); Logs().i('[Key Manager] Uploading ${dbSessions.length} room keys...'); // upload the payload... diff --git a/lib/encryption/ssss.dart b/lib/encryption/ssss.dart index 7d33b866..1d9819a4 100644 --- a/lib/encryption/ssss.dart +++ b/lib/encryption/ssss.dart @@ -26,7 +26,6 @@ import 'package:crypto/crypto.dart'; import '../matrix.dart'; import '../src/utils/crypto/crypto.dart' as uc; -import '../src/utils/run_in_background.dart'; import '../src/utils/run_in_root.dart'; import 'encryption.dart'; import 'utils/ssss_cache.dart'; @@ -201,14 +200,15 @@ class SSSS { content.passphrase.iterations = pbkdf2DefaultIterations; ; content.passphrase.bits = ssssKeyLength * 8; - privateKey = await runInBackground( - _keyFromPassphrase, - _KeyFromPassphraseArgs( - passphrase: passphrase, - info: content.passphrase, - ), - timeout: Duration(seconds: 10), - ); + privateKey = await client + .runInBackground( + _keyFromPassphrase, + _KeyFromPassphraseArgs( + passphrase: passphrase, + info: content.passphrase, + ), + ) + .timeout(Duration(seconds: 10)); } else { // we need to just generate a new key from scratch privateKey = Uint8List.fromList(uc.secureRandomBytes(ssssKeyLength)); @@ -636,14 +636,15 @@ class OpenSSSS { throw Exception( 'Tried to unlock with passphrase while key does not have a passphrase'); } - privateKey = await runInBackground( - _keyFromPassphrase, - _KeyFromPassphraseArgs( - passphrase: passphrase, - info: keyData.passphrase, - ), - timeout: Duration(seconds: 10), - ); + privateKey = await ssss.client + .runInBackground( + _keyFromPassphrase, + _KeyFromPassphraseArgs( + passphrase: passphrase, + info: keyData.passphrase, + ), + ) + .timeout(Duration(seconds: 10)); } else if (recoveryKey != null) { privateKey = SSSS.decodeRecoveryKey(recoveryKey); } else { diff --git a/lib/src/client.dart b/lib/src/client.dart index 70479dab..a063bf7e 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -93,6 +93,17 @@ class Client extends MatrixApi { String syncFilterId; + final Future Function(FutureOr Function(Q), Q, + {String debugLabel}) compute; + + Future runInBackground( + FutureOr Function(U arg) function, U arg) async { + if (compute != null) { + return await compute(function, arg); + } + return await function(arg); + } + /// Create a client /// [clientName] = unique identifier of this client /// [databaseBuilder]: A function that creates the database instance, that will be used. @@ -127,6 +138,8 @@ class Client extends MatrixApi { /// If your client supports more login types like login with token or SSO, then add this to /// [supportedLoginTypes]. Set a custom [syncFilter] if you like. By default the app /// will use lazy_load_members. + /// Set [compute] to the Flutter compute method to enable the SDK to run some + /// code in background. Client( this.clientName, { this.databaseBuilder, @@ -142,6 +155,7 @@ class Client extends MatrixApi { this.sendMessageTimeoutSeconds = 60, this.requestHistoryOnLimitedTimeline = false, this.supportedLoginTypes, + this.compute, Filter syncFilter, @deprecated bool debug, }) : syncFilter = syncFilter ?? diff --git a/lib/src/event.dart b/lib/src/event.dart index b6480c78..30d5606c 100644 --- a/lib/src/event.dart +++ b/lib/src/event.dart @@ -25,7 +25,6 @@ import '../matrix.dart'; import 'room.dart'; import 'utils/matrix_localizations.dart'; import 'utils/receipt.dart'; -import 'utils/run_in_background.dart'; import 'utils/event_localizations.dart'; import 'utils/crypto/encrypted_file.dart'; @@ -552,7 +551,7 @@ class Event extends MatrixEvent { k: fileMap['key']['k'], sha256: fileMap['hashes']['sha256'], ); - uint8list = await runInBackground(decryptFile, encryptedFile); + uint8list = await room.client.runInBackground(decryptFile, encryptedFile); } return MatrixFile(bytes: uint8list, name: body); } diff --git a/lib/src/utils/run_in_background.dart b/lib/src/utils/run_in_background.dart deleted file mode 100644 index adc298bc..00000000 --- a/lib/src/utils/run_in_background.dart +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Famedly Matrix SDK - * Copyright (C) 2020, 2021 Famedly GmbH - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import 'package:matrix/matrix.dart'; -import 'package:isolate/isolate.dart'; -import 'dart:async'; - -Future runInBackground( - FutureOr Function(U arg) function, - U arg, { - Duration timeout, - dynamic Function() onTimeout, -}) async { - IsolateRunner isolate; - try { - isolate = await IsolateRunner.spawn(); - } on UnsupportedError { - // web does not support isolates (yet), so we fall back to calling the method directly - return await function(arg); - } - final sub = isolate.errors - .listen((error) => Logs().e('Error caught in isolate', error)); - try { - return await isolate.run( - function, - arg, - timeout: timeout, - onTimeout: onTimeout, - ); - } finally { - await sub.cancel(); - await isolate.close(); - } -} diff --git a/pubspec.yaml b/pubspec.yaml index 8c6ea4d1..8ee84a55 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,6 @@ dependencies: crypto: ^3.0.0 base58check: ^2.0.0 olm: ^2.0.0 - isolate: ^2.0.3 matrix_api_lite: ^0.3.5 hive: ^2.0.4 ffi: ^1.0.0