chore: enable discarded_futures lint
BREAKING CHANGE: This changes the runInRoot method to not return a future. As a user, if you need the result of an async computation passed to runInRoot, please await it directly. Also the KeyVerification start and a few call methods now return a future.
This commit is contained in:
parent
5dc3adadfc
commit
8b8a647cf9
|
|
@ -6,6 +6,8 @@ linter:
|
||||||
always_use_package_imports: true
|
always_use_package_imports: true
|
||||||
avoid_bool_literals_in_conditional_expressions: true
|
avoid_bool_literals_in_conditional_expressions: true
|
||||||
avoid_print: true
|
avoid_print: true
|
||||||
|
cancel_subscriptions: true
|
||||||
|
discarded_futures: true
|
||||||
non_constant_identifier_names: false # seems to wrongly diagnose static const variables
|
non_constant_identifier_names: false # seems to wrongly diagnose static const variables
|
||||||
prefer_final_in_for_each: true
|
prefer_final_in_for_each: true
|
||||||
prefer_final_locals: true
|
prefer_final_locals: true
|
||||||
|
|
|
||||||
|
|
@ -100,11 +100,12 @@ class Encryption {
|
||||||
|
|
||||||
void handleDeviceOneTimeKeysCount(
|
void handleDeviceOneTimeKeysCount(
|
||||||
Map<String, int>? countJson, List<String>? unusedFallbackKeyTypes) {
|
Map<String, int>? countJson, List<String>? unusedFallbackKeyTypes) {
|
||||||
runInRoot(() => olmManager.handleDeviceOneTimeKeysCount(
|
runInRoot(() async => olmManager.handleDeviceOneTimeKeysCount(
|
||||||
countJson, unusedFallbackKeyTypes));
|
countJson, unusedFallbackKeyTypes));
|
||||||
}
|
}
|
||||||
|
|
||||||
void onSync() {
|
void onSync() {
|
||||||
|
// ignore: discarded_futures
|
||||||
keyVerificationManager.cleanup();
|
keyVerificationManager.cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,30 +119,25 @@ class Encryption {
|
||||||
.contains(event.type)) {
|
.contains(event.type)) {
|
||||||
// "just" room key request things. We don't need these asap, so we handle
|
// "just" room key request things. We don't need these asap, so we handle
|
||||||
// them in the background
|
// them in the background
|
||||||
// ignore: unawaited_futures
|
|
||||||
runInRoot(() => keyManager.handleToDeviceEvent(event));
|
runInRoot(() => keyManager.handleToDeviceEvent(event));
|
||||||
}
|
}
|
||||||
if (event.type == EventTypes.Dummy) {
|
if (event.type == EventTypes.Dummy) {
|
||||||
// the previous device just had to create a new olm session, due to olm session
|
// the previous device just had to create a new olm session, due to olm session
|
||||||
// corruption. We want to try to send it the last message we just sent it, if possible
|
// corruption. We want to try to send it the last message we just sent it, if possible
|
||||||
// ignore: unawaited_futures
|
|
||||||
runInRoot(() => olmManager.handleToDeviceEvent(event));
|
runInRoot(() => olmManager.handleToDeviceEvent(event));
|
||||||
}
|
}
|
||||||
if (event.type.startsWith('m.key.verification.')) {
|
if (event.type.startsWith('m.key.verification.')) {
|
||||||
// some key verification event. No need to handle it now, we can easily
|
// some key verification event. No need to handle it now, we can easily
|
||||||
// do this in the background
|
// do this in the background
|
||||||
|
|
||||||
// ignore: unawaited_futures
|
|
||||||
runInRoot(() => keyVerificationManager.handleToDeviceEvent(event));
|
runInRoot(() => keyVerificationManager.handleToDeviceEvent(event));
|
||||||
}
|
}
|
||||||
if (event.type.startsWith('m.secret.')) {
|
if (event.type.startsWith('m.secret.')) {
|
||||||
// some ssss thing. We can do this in the background
|
// some ssss thing. We can do this in the background
|
||||||
// ignore: unawaited_futures
|
|
||||||
runInRoot(() => ssss.handleToDeviceEvent(event));
|
runInRoot(() => ssss.handleToDeviceEvent(event));
|
||||||
}
|
}
|
||||||
if (event.sender == client.userID) {
|
if (event.sender == client.userID) {
|
||||||
// maybe we need to re-try SSSS secrets
|
// maybe we need to re-try SSSS secrets
|
||||||
// ignore: unawaited_futures
|
|
||||||
runInRoot(() => ssss.periodicallyRequestMissingCache());
|
runInRoot(() => ssss.periodicallyRequestMissingCache());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -157,14 +153,11 @@ class Encryption {
|
||||||
update.content['content']['msgtype']
|
update.content['content']['msgtype']
|
||||||
.startsWith('m.key.verification.'))) {
|
.startsWith('m.key.verification.'))) {
|
||||||
// "just" key verification, no need to do this in sync
|
// "just" key verification, no need to do this in sync
|
||||||
|
|
||||||
// ignore: unawaited_futures
|
|
||||||
runInRoot(() => keyVerificationManager.handleEventUpdate(update));
|
runInRoot(() => keyVerificationManager.handleEventUpdate(update));
|
||||||
}
|
}
|
||||||
if (update.content['sender'] == client.userID &&
|
if (update.content['sender'] == client.userID &&
|
||||||
update.content['unsigned']?['transaction_id'] == null) {
|
update.content['unsigned']?['transaction_id'] == null) {
|
||||||
// maybe we need to re-try SSSS secrets
|
// maybe we need to re-try SSSS secrets
|
||||||
// ignore: unawaited_futures
|
|
||||||
runInRoot(() => ssss.periodicallyRequestMissingCache());
|
runInRoot(() => ssss.periodicallyRequestMissingCache());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -239,6 +232,7 @@ class Encryption {
|
||||||
// the entry should always exist. In the case it doesn't, the following
|
// the entry should always exist. In the case it doesn't, the following
|
||||||
// line *could* throw an error. As that is a future, though, and we call
|
// line *could* throw an error. As that is a future, though, and we call
|
||||||
// it un-awaited here, nothing happens, which is exactly the result we want
|
// it un-awaited here, nothing happens, which is exactly the result we want
|
||||||
|
// ignore: discarded_futures
|
||||||
client.database?.updateInboundGroupSessionIndexes(
|
client.database?.updateInboundGroupSessionIndexes(
|
||||||
json.encode(inboundGroupSession.indexes), roomId, sessionId);
|
json.encode(inboundGroupSession.indexes), roomId, sessionId);
|
||||||
}
|
}
|
||||||
|
|
@ -252,7 +246,7 @@ class Encryption {
|
||||||
?.session_id() ??
|
?.session_id() ??
|
||||||
'') ==
|
'') ==
|
||||||
content.sessionId) {
|
content.sessionId) {
|
||||||
runInRoot(() =>
|
runInRoot(() async =>
|
||||||
keyManager.clearOrUseOutboundGroupSession(roomId, wipe: true));
|
keyManager.clearOrUseOutboundGroupSession(roomId, wipe: true));
|
||||||
}
|
}
|
||||||
if (canRequestSession) {
|
if (canRequestSession) {
|
||||||
|
|
|
||||||
|
|
@ -244,7 +244,8 @@ class KeyManager {
|
||||||
!client.isUnknownSession) {
|
!client.isUnknownSession) {
|
||||||
// do e2ee recovery
|
// do e2ee recovery
|
||||||
_requestedSessionIds.add(requestIdent);
|
_requestedSessionIds.add(requestIdent);
|
||||||
runInRoot(() => request(
|
|
||||||
|
runInRoot(() async => request(
|
||||||
room,
|
room,
|
||||||
sessionId,
|
sessionId,
|
||||||
senderKey,
|
senderKey,
|
||||||
|
|
@ -775,8 +776,8 @@ class KeyManager {
|
||||||
Future<void>? _uploadingFuture;
|
Future<void>? _uploadingFuture;
|
||||||
|
|
||||||
void startAutoUploadKeys() {
|
void startAutoUploadKeys() {
|
||||||
_uploadKeysOnSync = encryption.client.onSync.stream
|
_uploadKeysOnSync = encryption.client.onSync.stream.listen(
|
||||||
.listen((_) => uploadInboundGroupSessions(skipIfInProgress: true));
|
(_) async => uploadInboundGroupSessions(skipIfInProgress: true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This task should be performed after sync processing but should not block
|
/// This task should be performed after sync processing but should not block
|
||||||
|
|
@ -1064,6 +1065,7 @@ class KeyManager {
|
||||||
StreamSubscription<SyncUpdate>? _uploadKeysOnSync;
|
StreamSubscription<SyncUpdate>? _uploadKeysOnSync;
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
// ignore: discarded_futures
|
||||||
_uploadKeysOnSync?.cancel();
|
_uploadKeysOnSync?.cancel();
|
||||||
for (final sess in _outboundGroupSessions.values) {
|
for (final sess in _outboundGroupSessions.values) {
|
||||||
sess.dispose();
|
sess.dispose();
|
||||||
|
|
|
||||||
|
|
@ -396,20 +396,24 @@ class OlmManager {
|
||||||
final device = client.userDeviceKeys[event.sender]?.deviceKeys.values
|
final device = client.userDeviceKeys[event.sender]?.deviceKeys.values
|
||||||
.firstWhereOrNull((d) => d.curve25519Key == senderKey);
|
.firstWhereOrNull((d) => d.curve25519Key == senderKey);
|
||||||
final existingSessions = olmSessions[senderKey];
|
final existingSessions = olmSessions[senderKey];
|
||||||
Future<void> updateSessionUsage([OlmSession? session]) =>
|
Future<void> updateSessionUsage([OlmSession? session]) async {
|
||||||
runInRoot(() async {
|
try {
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
session.lastReceived = DateTime.now();
|
session.lastReceived = DateTime.now();
|
||||||
await storeOlmSession(session);
|
await storeOlmSession(session);
|
||||||
}
|
}
|
||||||
if (device != null) {
|
if (device != null) {
|
||||||
device.lastActive = DateTime.now();
|
device.lastActive = DateTime.now();
|
||||||
await encryption.olmDatabase?.setLastActiveUserDeviceKey(
|
await encryption.olmDatabase?.setLastActiveUserDeviceKey(
|
||||||
device.lastActive.millisecondsSinceEpoch,
|
device.lastActive.millisecondsSinceEpoch,
|
||||||
device.userId,
|
device.userId,
|
||||||
device.deviceId!);
|
device.deviceId!);
|
||||||
}
|
}
|
||||||
});
|
} catch (e, s) {
|
||||||
|
Logs().e('Error while updating olm session timestamp', e, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (existingSessions != null) {
|
if (existingSessions != null) {
|
||||||
for (final session in existingSessions) {
|
for (final session in existingSessions) {
|
||||||
if (session.session == null) {
|
if (session.session == null) {
|
||||||
|
|
@ -446,14 +450,16 @@ class OlmManager {
|
||||||
newSession.create_inbound_from(_olmAccount!, senderKey, body);
|
newSession.create_inbound_from(_olmAccount!, senderKey, body);
|
||||||
_olmAccount!.remove_one_time_keys(newSession);
|
_olmAccount!.remove_one_time_keys(newSession);
|
||||||
await encryption.olmDatabase?.updateClientKeys(pickledOlmAccount!);
|
await encryption.olmDatabase?.updateClientKeys(pickledOlmAccount!);
|
||||||
|
|
||||||
plaintext = newSession.decrypt(type, body);
|
plaintext = newSession.decrypt(type, body);
|
||||||
await runInRoot(() => storeOlmSession(OlmSession(
|
|
||||||
key: client.userID!,
|
await storeOlmSession(OlmSession(
|
||||||
identityKey: senderKey,
|
key: client.userID!,
|
||||||
sessionId: newSession.session_id(),
|
identityKey: senderKey,
|
||||||
session: newSession,
|
sessionId: newSession.session_id(),
|
||||||
lastReceived: DateTime.now(),
|
session: newSession,
|
||||||
)));
|
lastReceived: DateTime.now(),
|
||||||
|
));
|
||||||
await updateSessionUsage();
|
await updateSessionUsage();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
newSession.free();
|
newSession.free();
|
||||||
|
|
@ -570,8 +576,6 @@ class OlmManager {
|
||||||
return _decryptToDeviceEvent(event);
|
return _decryptToDeviceEvent(event);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
// okay, the thing errored while decrypting. It is safe to assume that the olm session is corrupt and we should generate a new one
|
// okay, the thing errored while decrypting. It is safe to assume that the olm session is corrupt and we should generate a new one
|
||||||
|
|
||||||
// ignore: unawaited_futures
|
|
||||||
runInRoot(() => restoreOlmSession(event.senderId, senderKey));
|
runInRoot(() => restoreOlmSession(event.senderId, senderKey));
|
||||||
|
|
||||||
rethrow;
|
rethrow;
|
||||||
|
|
@ -658,14 +662,18 @@ class OlmManager {
|
||||||
final encryptResult = sess.first.session!.encrypt(json.encode(fullPayload));
|
final encryptResult = sess.first.session!.encrypt(json.encode(fullPayload));
|
||||||
await storeOlmSession(sess.first);
|
await storeOlmSession(sess.first);
|
||||||
if (encryption.olmDatabase != null) {
|
if (encryption.olmDatabase != null) {
|
||||||
await runInRoot(
|
try {
|
||||||
() async => encryption.olmDatabase?.setLastSentMessageUserDeviceKey(
|
await encryption.olmDatabase?.setLastSentMessageUserDeviceKey(
|
||||||
json.encode({
|
json.encode({
|
||||||
'type': type,
|
'type': type,
|
||||||
'content': payload,
|
'content': payload,
|
||||||
}),
|
}),
|
||||||
device.userId,
|
device.userId,
|
||||||
device.deviceId!));
|
device.deviceId!);
|
||||||
|
} catch (e, s) {
|
||||||
|
// we can ignore this error, since it would just make us use a different olm session possibly
|
||||||
|
Logs().w('Error while updating olm usage timestamp', e, s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
final encryptedBody = <String, dynamic>{
|
final encryptedBody = <String, dynamic>{
|
||||||
'algorithm': AlgorithmTypes.olmV1Curve25519AesSha2,
|
'algorithm': AlgorithmTypes.olmV1Curve25519AesSha2,
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ import 'package:matrix/encryption/utils/ssss_cache.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:matrix/src/utils/cached_stream_controller.dart';
|
import 'package:matrix/src/utils/cached_stream_controller.dart';
|
||||||
import 'package:matrix/src/utils/crypto/crypto.dart' as uc;
|
import 'package:matrix/src/utils/crypto/crypto.dart' as uc;
|
||||||
import 'package:matrix/src/utils/run_in_root.dart';
|
|
||||||
|
|
||||||
const cacheTypes = <String>{
|
const cacheTypes = <String>{
|
||||||
EventTypes.CrossSigningSelfSigning,
|
EventTypes.CrossSigningSelfSigning,
|
||||||
|
|
@ -722,7 +721,11 @@ class OpenSSSS {
|
||||||
throw InvalidPassphraseException('Inalid key');
|
throw InvalidPassphraseException('Inalid key');
|
||||||
}
|
}
|
||||||
if (postUnlock) {
|
if (postUnlock) {
|
||||||
await runInRoot(() => _postUnlock());
|
try {
|
||||||
|
await _postUnlock();
|
||||||
|
} catch (e, s) {
|
||||||
|
Logs().e('Error during post unlock', e, s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import 'dart:typed_data';
|
||||||
|
|
||||||
/// decodes base64
|
/// decodes base64
|
||||||
///
|
///
|
||||||
/// Dart's native [base64.decode] requires a padded base64 input String.
|
/// Dart's native [base64.decode()] requires a padded base64 input String.
|
||||||
/// This function allows unpadded base64 too.
|
/// This function allows unpadded base64 too.
|
||||||
///
|
///
|
||||||
/// See: https://github.com/dart-lang/sdk/issues/39510
|
/// See: https://github.com/dart-lang/sdk/issues/39510
|
||||||
|
|
|
||||||
|
|
@ -1636,7 +1636,7 @@ class Client extends MatrixApi {
|
||||||
set backgroundSync(bool enabled) {
|
set backgroundSync(bool enabled) {
|
||||||
_backgroundSync = enabled;
|
_backgroundSync = enabled;
|
||||||
if (_backgroundSync) {
|
if (_backgroundSync) {
|
||||||
_sync();
|
runInRoot(() async => _sync());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2232,7 +2232,7 @@ class Client extends MatrixApi {
|
||||||
requestHistoryOnLimitedTimeline) {
|
requestHistoryOnLimitedTimeline) {
|
||||||
Logs().v(
|
Logs().v(
|
||||||
'Limited timeline for ${rooms[roomIndex].id} request history now');
|
'Limited timeline for ${rooms[roomIndex].id} request history now');
|
||||||
unawaited(runInRoot(rooms[roomIndex].requestHistory));
|
runInRoot(rooms[roomIndex].requestHistory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return room;
|
return room;
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,7 @@ class Event extends MatrixEvent {
|
||||||
final json = toJson();
|
final json = toJson();
|
||||||
json['unsigned'] ??= <String, dynamic>{};
|
json['unsigned'] ??= <String, dynamic>{};
|
||||||
json['unsigned'][messageSendingStatusKey] = EventStatus.error.intValue;
|
json['unsigned'][messageSendingStatusKey] = EventStatus.error.intValue;
|
||||||
|
// ignore: discarded_futures
|
||||||
room.client.handleSync(
|
room.client.handleSync(
|
||||||
SyncUpdate(
|
SyncUpdate(
|
||||||
nextBatch: '',
|
nextBatch: '',
|
||||||
|
|
@ -154,6 +155,7 @@ class Event extends MatrixEvent {
|
||||||
MessageTypes.File,
|
MessageTypes.File,
|
||||||
}.contains(messageType) &&
|
}.contains(messageType) &&
|
||||||
!room.sendingFilePlaceholders.containsKey(eventId)) {
|
!room.sendingFilePlaceholders.containsKey(eventId)) {
|
||||||
|
// ignore: discarded_futures
|
||||||
remove();
|
remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1620,6 +1620,7 @@ class Room {
|
||||||
return user.asUser;
|
return user.asUser;
|
||||||
} else {
|
} else {
|
||||||
if (mxID.isValidMatrixId) {
|
if (mxID.isValidMatrixId) {
|
||||||
|
// ignore: discarded_futures
|
||||||
requestUser(
|
requestUser(
|
||||||
mxID,
|
mxID,
|
||||||
ignoreErrors: true,
|
ignoreErrors: true,
|
||||||
|
|
|
||||||
|
|
@ -300,8 +300,11 @@ class Timeline {
|
||||||
|
|
||||||
/// Don't forget to call this before you dismiss this object!
|
/// Don't forget to call this before you dismiss this object!
|
||||||
void cancelSubscriptions() {
|
void cancelSubscriptions() {
|
||||||
|
// ignore: discarded_futures
|
||||||
sub?.cancel();
|
sub?.cancel();
|
||||||
|
// ignore: discarded_futures
|
||||||
roomSub?.cancel();
|
roomSub?.cancel();
|
||||||
|
// ignore: discarded_futures
|
||||||
sessionIdReceivedSub?.cancel();
|
sessionIdReceivedSub?.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -504,7 +504,7 @@ class DeviceKeys extends SignableKey {
|
||||||
lastActive = DateTime.fromMillisecondsSinceEpoch(0);
|
lastActive = DateTime.fromMillisecondsSinceEpoch(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyVerification startVerification() {
|
Future<KeyVerification> startVerification() async {
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
throw Exception('setVerification called on invalid key');
|
throw Exception('setVerification called on invalid key');
|
||||||
}
|
}
|
||||||
|
|
@ -516,7 +516,7 @@ class DeviceKeys extends SignableKey {
|
||||||
final request = KeyVerification(
|
final request = KeyVerification(
|
||||||
encryption: encryption, userId: userId, deviceId: deviceId!);
|
encryption: encryption, userId: userId, deviceId: deviceId!);
|
||||||
|
|
||||||
request.start();
|
await request.start();
|
||||||
encryption.keyVerificationManager.addRequest(request);
|
encryption.keyVerificationManager.addRequest(request);
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,9 @@ abstract class NativeImplementations {
|
||||||
bool retryInDummy = false,
|
bool retryInDummy = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
|
||||||
|
|
||||||
/// this implementation will catch any non-implemented method
|
/// this implementation will catch any non-implemented method
|
||||||
dynamic noSuchMethod(Invocation invocation) {
|
@override
|
||||||
|
dynamic noSuchMethod(Invocation invocation) async {
|
||||||
final dynamic argument = invocation.positionalArguments.single;
|
final dynamic argument = invocation.positionalArguments.single;
|
||||||
final memberName = invocation.memberName.toString().split('"')[1];
|
final memberName = invocation.memberName.toString().split('"')[1];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,13 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
Future<T?> runInRoot<T>(FutureOr<T> Function() fn) async {
|
void runInRoot<T>(FutureOr<T> Function() fn) {
|
||||||
return await Zone.root.run(() async {
|
// ignore: discarded_futures
|
||||||
|
Zone.root.run(() async {
|
||||||
try {
|
try {
|
||||||
return await fn();
|
await fn();
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logs().e('Error thrown in root zone', e, s);
|
Logs().e('Error thrown in root zone', e, s);
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ class UiaRequest<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
UiaRequest({this.onUpdate, required this.request}) {
|
UiaRequest({this.onUpdate, required this.request}) {
|
||||||
|
// ignore: discarded_futures
|
||||||
_run();
|
_run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ class NativeImplementationsWebWorker extends NativeImplementations {
|
||||||
return completer.future.timeout(timeout);
|
return completer.future.timeout(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleIncomingMessage(MessageEvent event) {
|
Future<void> _handleIncomingMessage(MessageEvent event) async {
|
||||||
final data = event.data;
|
final data = event.data;
|
||||||
// don't forget handling errors of our second thread...
|
// don't forget handling errors of our second thread...
|
||||||
if (data['label'] == 'stacktrace') {
|
if (data['label'] == 'stacktrace') {
|
||||||
|
|
@ -46,12 +46,10 @@ class NativeImplementationsWebWorker extends NativeImplementations {
|
||||||
|
|
||||||
final error = event.data['error']!;
|
final error = event.data['error']!;
|
||||||
|
|
||||||
Future.value(
|
final stackTrace =
|
||||||
onStackTrace.call(event.data['stacktrace'] as String),
|
await onStackTrace.call(event.data['stacktrace'] as String);
|
||||||
).then(
|
completer?.completeError(
|
||||||
(stackTrace) => completer?.completeError(
|
WebWorkerError(error: error, stackTrace: stackTrace),
|
||||||
WebWorkerError(error: error, stackTrace: stackTrace),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
final response = WebWorkerData.fromJson(event.data);
|
final response = WebWorkerData.fromJson(event.data);
|
||||||
|
|
|
||||||
|
|
@ -522,17 +522,18 @@ class CallSession {
|
||||||
await gotCallFeedsForAnswer(callFeeds);
|
await gotCallFeedsForAnswer(callFeeds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void replacedBy(CallSession newCall) {
|
Future<void> replacedBy(CallSession newCall) async {
|
||||||
if (state == CallState.kWaitLocalMedia) {
|
if (state == CallState.kWaitLocalMedia) {
|
||||||
Logs().v('Telling new call to wait for local media');
|
Logs().v('Telling new call to wait for local media');
|
||||||
newCall.waitForLocalAVStream = true;
|
newCall.waitForLocalAVStream = true;
|
||||||
} else if (state == CallState.kCreateOffer ||
|
} else if (state == CallState.kCreateOffer ||
|
||||||
state == CallState.kInviteSent) {
|
state == CallState.kInviteSent) {
|
||||||
Logs().v('Handing local stream to new call');
|
Logs().v('Handing local stream to new call');
|
||||||
newCall.gotCallFeedsForAnswer(getLocalStreams);
|
await newCall.gotCallFeedsForAnswer(getLocalStreams);
|
||||||
}
|
}
|
||||||
successor = newCall;
|
successor = newCall;
|
||||||
onCallReplaced.add(newCall);
|
onCallReplaced.add(newCall);
|
||||||
|
// ignore: unawaited_futures
|
||||||
hangup(CallErrorCode.Replaced, true);
|
hangup(CallErrorCode.Replaced, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1510,8 +1511,9 @@ class CallSession {
|
||||||
return pc;
|
return pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void createDataChannel(String label, RTCDataChannelInit dataChannelDict) {
|
Future<void> createDataChannel(
|
||||||
pc?.createDataChannel(label, dataChannelDict);
|
String label, RTCDataChannelInit dataChannelDict) async {
|
||||||
|
await pc?.createDataChannel(label, dataChannelDict);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> tryRemoveStopedStreams() async {
|
Future<void> tryRemoveStopedStreams() async {
|
||||||
|
|
|
||||||
|
|
@ -45,11 +45,15 @@ class ConnectionTester {
|
||||||
|
|
||||||
await pc1!.setRemoteDescription(answer);
|
await pc1!.setRemoteDescription(answer);
|
||||||
|
|
||||||
void dispose() {
|
Future<void> dispose() async {
|
||||||
pc1!.close();
|
await Future.wait([
|
||||||
pc1!.dispose();
|
pc1!.close(),
|
||||||
pc2!.close();
|
pc2!.close(),
|
||||||
pc2!.dispose();
|
]);
|
||||||
|
await Future.wait([
|
||||||
|
pc1!.dispose(),
|
||||||
|
pc2!.dispose(),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool connected = false;
|
bool connected = false;
|
||||||
|
|
@ -69,6 +73,7 @@ class ConnectionTester {
|
||||||
.e('[VOIP] ConnectionTester Error while testing TURN server: ', e, s);
|
.e('[VOIP] ConnectionTester Error while testing TURN server: ', e, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ignore: unawaited_futures
|
||||||
dispose();
|
dispose();
|
||||||
return connected;
|
return connected;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -232,11 +232,11 @@ class GroupCall {
|
||||||
this.groupCallId = groupCallId ?? genCallID();
|
this.groupCallId = groupCallId ?? genCallID();
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupCall create() {
|
Future<GroupCall> create() async {
|
||||||
voip.groupCalls[groupCallId] = this;
|
voip.groupCalls[groupCallId] = this;
|
||||||
voip.groupCalls[room.id] = this;
|
voip.groupCalls[room.id] = this;
|
||||||
|
|
||||||
client.setRoomStateWithKey(
|
await client.setRoomStateWithKey(
|
||||||
room.id,
|
room.id,
|
||||||
EventTypes.GroupCallPrefix,
|
EventTypes.GroupCallPrefix,
|
||||||
groupCallId,
|
groupCallId,
|
||||||
|
|
@ -413,6 +413,7 @@ class GroupCall {
|
||||||
if (localUserMediaStream != null) {
|
if (localUserMediaStream != null) {
|
||||||
final oldStream = localUserMediaStream!.stream;
|
final oldStream = localUserMediaStream!.stream;
|
||||||
localUserMediaStream!.setNewStream(stream.stream!);
|
localUserMediaStream!.setNewStream(stream.stream!);
|
||||||
|
// ignore: discarded_futures
|
||||||
stopMediaStream(oldStream);
|
stopMediaStream(oldStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ class VoIP {
|
||||||
for (final room in client.rooms) {
|
for (final room in client.rooms) {
|
||||||
if (room.activeGroupCallEvents.isNotEmpty) {
|
if (room.activeGroupCallEvents.isNotEmpty) {
|
||||||
for (final groupCall in room.activeGroupCallEvents) {
|
for (final groupCall in room.activeGroupCallEvents) {
|
||||||
|
// ignore: discarded_futures
|
||||||
createGroupCallFromRoomStateEvent(groupCall,
|
createGroupCallFromRoomStateEvent(groupCall,
|
||||||
emitHandleNewGroupCall: false);
|
emitHandleNewGroupCall: false);
|
||||||
}
|
}
|
||||||
|
|
@ -589,7 +590,7 @@ class VoIP {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final groupId = genCallID();
|
final groupId = genCallID();
|
||||||
final groupCall = GroupCall(
|
final groupCall = await GroupCall(
|
||||||
groupCallId: groupId,
|
groupCallId: groupId,
|
||||||
client: client,
|
client: client,
|
||||||
voip: this,
|
voip: this,
|
||||||
|
|
|
||||||
|
|
@ -1137,8 +1137,8 @@ void main() {
|
||||||
reason: '!5345234235:example.com not found as archived room');
|
reason: '!5345234235:example.com not found as archived room');
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() async {
|
||||||
matrix.dispose(closeDatabase: true);
|
await matrix.dispose(closeDatabase: true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import 'package:matrix/matrix.dart';
|
||||||
import 'fake_database.dart';
|
import 'fake_database.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('HiveCollections Database Test', () {
|
group('HiveCollections Database Test', () async {
|
||||||
testDatabase(
|
testDatabase(
|
||||||
getHiveCollectionsDatabase(null),
|
getHiveCollectionsDatabase(null),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -249,7 +249,7 @@ void main() {
|
||||||
|
|
||||||
test('start verification', () async {
|
test('start verification', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
var req = client
|
var req = await client
|
||||||
.userDeviceKeys['@alice:example.com']?.deviceKeys['JLAFKJWSCS']
|
.userDeviceKeys['@alice:example.com']?.deviceKeys['JLAFKJWSCS']
|
||||||
?.startVerification();
|
?.startVerification();
|
||||||
expect(req != null, true);
|
expect(req != null, true);
|
||||||
|
|
|
||||||
|
|
@ -260,6 +260,7 @@ class FakeMatrixApi extends BaseClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// and generate a fake sync
|
// and generate a fake sync
|
||||||
|
// ignore: discarded_futures
|
||||||
_client!.handleSync(sdk.SyncUpdate(nextBatch: ''));
|
_client!.handleSync(sdk.SyncUpdate(nextBatch: ''));
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ void main() {
|
||||||
insertList.clear();
|
insertList.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() => client.dispose().onError((e, s) {}));
|
tearDown(() async => client.dispose().onError((e, s) {}));
|
||||||
|
|
||||||
test('archive room not loaded', () async {
|
test('archive room not loaded', () async {
|
||||||
final archiveRoom =
|
final archiveRoom =
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ void main() {
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
|
|
||||||
final countStream = StreamController<int>.broadcast();
|
final countStream = StreamController<int>.broadcast();
|
||||||
Future<int> waitForCount(int count) {
|
Future<int> waitForCount(int count) async {
|
||||||
if (updateCount == count) {
|
if (updateCount == count) {
|
||||||
return Future.value(updateCount);
|
return Future.value(updateCount);
|
||||||
}
|
}
|
||||||
|
|
@ -46,9 +46,9 @@ void main() {
|
||||||
final completer = Completer<int>();
|
final completer = Completer<int>();
|
||||||
|
|
||||||
StreamSubscription<int>? sub;
|
StreamSubscription<int>? sub;
|
||||||
sub = countStream.stream.listen((newCount) {
|
sub = countStream.stream.listen((newCount) async {
|
||||||
if (newCount == count) {
|
if (newCount == count) {
|
||||||
sub?.cancel();
|
await sub?.cancel();
|
||||||
completer.complete(count);
|
completer.complete(count);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -100,7 +100,8 @@ void main() {
|
||||||
testTimeStamp = DateTime.now().millisecondsSinceEpoch;
|
testTimeStamp = DateTime.now().millisecondsSinceEpoch;
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() => client.dispose(closeDatabase: true).onError((e, s) {}));
|
tearDown(
|
||||||
|
() async => client.dispose(closeDatabase: true).onError((e, s) {}));
|
||||||
|
|
||||||
test('Request future', () async {
|
test('Request future', () async {
|
||||||
timeline.events.clear();
|
timeline.events.clear();
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ void main() {
|
||||||
var currentPoison = 0;
|
var currentPoison = 0;
|
||||||
|
|
||||||
final countStream = StreamController<int>.broadcast();
|
final countStream = StreamController<int>.broadcast();
|
||||||
Future<int> waitForCount(int count) {
|
Future<int> waitForCount(int count) async {
|
||||||
if (updateCount == count) {
|
if (updateCount == count) {
|
||||||
return Future.value(updateCount);
|
return Future.value(updateCount);
|
||||||
}
|
}
|
||||||
|
|
@ -47,9 +47,9 @@ void main() {
|
||||||
final completer = Completer<int>();
|
final completer = Completer<int>();
|
||||||
|
|
||||||
StreamSubscription<int>? sub;
|
StreamSubscription<int>? sub;
|
||||||
sub = countStream.stream.listen((newCount) {
|
sub = countStream.stream.listen((newCount) async {
|
||||||
if (newCount == count) {
|
if (newCount == count) {
|
||||||
sub?.cancel();
|
await sub?.cancel();
|
||||||
completer.complete(count);
|
completer.complete(count);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -109,7 +109,8 @@ void main() {
|
||||||
testTimeStamp = DateTime.now().millisecondsSinceEpoch;
|
testTimeStamp = DateTime.now().millisecondsSinceEpoch;
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() => client.dispose(closeDatabase: true).onError((e, s) {}));
|
tearDown(
|
||||||
|
() async => client.dispose(closeDatabase: true).onError((e, s) {}));
|
||||||
|
|
||||||
test('Create', () async {
|
test('Create', () async {
|
||||||
client.onEvent.add(EventUpdate(
|
client.onEvent.add(EventUpdate(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue