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.
This commit is contained in:
Christian Pauly 2021-07-21 11:51:08 +02:00
parent 66b5f4954e
commit 209035ffbd
6 changed files with 34 additions and 71 deletions

View File

@ -25,7 +25,6 @@ import './encryption.dart';
import './utils/outbound_group_session.dart'; import './utils/outbound_group_session.dart';
import './utils/session_key.dart'; import './utils/session_key.dart';
import '../matrix.dart'; import '../matrix.dart';
import '../src/utils/run_in_background.dart';
import '../src/utils/run_in_root.dart'; import '../src/utils/run_in_root.dart';
const megolmKey = EventTypes.MegolmBackup; const megolmKey = EventTypes.MegolmBackup;
@ -734,7 +733,7 @@ class KeyManager {
} }
} }
final roomKeys = final roomKeys =
await runInBackground<RoomKeys, _GenerateUploadKeysArgs>( await client.runInBackground<RoomKeys, _GenerateUploadKeysArgs>(
_generateUploadKeys, args); _generateUploadKeys, args);
Logs().i('[Key Manager] Uploading ${dbSessions.length} room keys...'); Logs().i('[Key Manager] Uploading ${dbSessions.length} room keys...');
// upload the payload... // upload the payload...

View File

@ -26,7 +26,6 @@ import 'package:crypto/crypto.dart';
import '../matrix.dart'; import '../matrix.dart';
import '../src/utils/crypto/crypto.dart' as uc; import '../src/utils/crypto/crypto.dart' as uc;
import '../src/utils/run_in_background.dart';
import '../src/utils/run_in_root.dart'; import '../src/utils/run_in_root.dart';
import 'encryption.dart'; import 'encryption.dart';
import 'utils/ssss_cache.dart'; import 'utils/ssss_cache.dart';
@ -201,14 +200,15 @@ class SSSS {
content.passphrase.iterations = pbkdf2DefaultIterations; content.passphrase.iterations = pbkdf2DefaultIterations;
; ;
content.passphrase.bits = ssssKeyLength * 8; content.passphrase.bits = ssssKeyLength * 8;
privateKey = await runInBackground( privateKey = await client
_keyFromPassphrase, .runInBackground(
_KeyFromPassphraseArgs( _keyFromPassphrase,
passphrase: passphrase, _KeyFromPassphraseArgs(
info: content.passphrase, passphrase: passphrase,
), info: content.passphrase,
timeout: Duration(seconds: 10), ),
); )
.timeout(Duration(seconds: 10));
} else { } else {
// we need to just generate a new key from scratch // we need to just generate a new key from scratch
privateKey = Uint8List.fromList(uc.secureRandomBytes(ssssKeyLength)); privateKey = Uint8List.fromList(uc.secureRandomBytes(ssssKeyLength));
@ -636,14 +636,15 @@ class OpenSSSS {
throw Exception( throw Exception(
'Tried to unlock with passphrase while key does not have a passphrase'); 'Tried to unlock with passphrase while key does not have a passphrase');
} }
privateKey = await runInBackground( privateKey = await ssss.client
_keyFromPassphrase, .runInBackground(
_KeyFromPassphraseArgs( _keyFromPassphrase,
passphrase: passphrase, _KeyFromPassphraseArgs(
info: keyData.passphrase, passphrase: passphrase,
), info: keyData.passphrase,
timeout: Duration(seconds: 10), ),
); )
.timeout(Duration(seconds: 10));
} else if (recoveryKey != null) { } else if (recoveryKey != null) {
privateKey = SSSS.decodeRecoveryKey(recoveryKey); privateKey = SSSS.decodeRecoveryKey(recoveryKey);
} else { } else {

View File

@ -93,6 +93,17 @@ class Client extends MatrixApi {
String syncFilterId; String syncFilterId;
final Future<R> Function<Q, R>(FutureOr<R> Function(Q), Q,
{String debugLabel}) compute;
Future<T> runInBackground<T, U>(
FutureOr<T> Function(U arg) function, U arg) async {
if (compute != null) {
return await compute(function, arg);
}
return await function(arg);
}
/// Create a client /// Create a client
/// [clientName] = unique identifier of this client /// [clientName] = unique identifier of this client
/// [databaseBuilder]: A function that creates the database instance, that will be used. /// [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 /// 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 /// [supportedLoginTypes]. Set a custom [syncFilter] if you like. By default the app
/// will use lazy_load_members. /// will use lazy_load_members.
/// Set [compute] to the Flutter compute method to enable the SDK to run some
/// code in background.
Client( Client(
this.clientName, { this.clientName, {
this.databaseBuilder, this.databaseBuilder,
@ -142,6 +155,7 @@ class Client extends MatrixApi {
this.sendMessageTimeoutSeconds = 60, this.sendMessageTimeoutSeconds = 60,
this.requestHistoryOnLimitedTimeline = false, this.requestHistoryOnLimitedTimeline = false,
this.supportedLoginTypes, this.supportedLoginTypes,
this.compute,
Filter syncFilter, Filter syncFilter,
@deprecated bool debug, @deprecated bool debug,
}) : syncFilter = syncFilter ?? }) : syncFilter = syncFilter ??

View File

@ -25,7 +25,6 @@ import '../matrix.dart';
import 'room.dart'; import 'room.dart';
import 'utils/matrix_localizations.dart'; import 'utils/matrix_localizations.dart';
import 'utils/receipt.dart'; import 'utils/receipt.dart';
import 'utils/run_in_background.dart';
import 'utils/event_localizations.dart'; import 'utils/event_localizations.dart';
import 'utils/crypto/encrypted_file.dart'; import 'utils/crypto/encrypted_file.dart';
@ -552,7 +551,7 @@ class Event extends MatrixEvent {
k: fileMap['key']['k'], k: fileMap['key']['k'],
sha256: fileMap['hashes']['sha256'], sha256: fileMap['hashes']['sha256'],
); );
uint8list = await runInBackground(decryptFile, encryptedFile); uint8list = await room.client.runInBackground(decryptFile, encryptedFile);
} }
return MatrixFile(bytes: uint8list, name: body); return MatrixFile(bytes: uint8list, name: body);
} }

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
import 'package:matrix/matrix.dart';
import 'package:isolate/isolate.dart';
import 'dart:async';
Future<T> runInBackground<T, U>(
FutureOr<T> 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();
}
}

View File

@ -17,7 +17,6 @@ dependencies:
crypto: ^3.0.0 crypto: ^3.0.0
base58check: ^2.0.0 base58check: ^2.0.0
olm: ^2.0.0 olm: ^2.0.0
isolate: ^2.0.3
matrix_api_lite: ^0.3.5 matrix_api_lite: ^0.3.5
hive: ^2.0.4 hive: ^2.0.4
ffi: ^1.0.0 ffi: ^1.0.0