73
73
import org .matrix .androidsdk .crypto .interfaces .CryptoRoomState ;
74
74
import org .matrix .androidsdk .crypto .interfaces .CryptoSession ;
75
75
import org .matrix .androidsdk .crypto .interfaces .CryptoSyncResponse ;
76
+ import org .matrix .androidsdk .crypto .internal .otk .OneTimeKeysResponseHandler ;
76
77
import org .matrix .androidsdk .crypto .keysbackup .KeysBackup ;
77
78
import org .matrix .androidsdk .crypto .model .crypto .KeysUploadResponse ;
78
79
import org .matrix .androidsdk .crypto .model .crypto .RoomKeyContent ;
@@ -138,6 +139,8 @@ public class MXCryptoImpl implements MXCrypto {
138
139
139
140
private Map <String , Map <String , String >> mLastPublishedOneTimeKeys ;
140
141
142
+ private OneTimeKeysResponseHandler oneTimeKeysResponseHandler = new OneTimeKeysResponseHandler (this );
143
+
141
144
// the encryption is starting
142
145
private boolean mIsStarting ;
143
146
@@ -300,7 +303,7 @@ public MXCryptoImpl(@NonNull CryptoSession matrixSession,
300
303
mCryptoStore .storeUserDevices (mSession .getMyUserId (), myDevices );
301
304
302
305
// Create the VerificationManager before setting the CryptoEventsListener, to avoid crash (vector-im/riot-android#3396)
303
- mShortCodeVerificationManager = new VerificationManager (mSession );
306
+ mShortCodeVerificationManager = new VerificationManager (mSession , this );
304
307
305
308
mSession .getDataHandler ().setCryptoEventsListener (mEventListener );
306
309
@@ -1107,6 +1110,7 @@ public void ensureOlmSessionsForDevices(final Map<String, List<MXDeviceInfo>> de
1107
1110
}
1108
1111
1109
1112
if (devicesWithoutSession .size () == 0 ) {
1113
+ Log .d (LOG_TAG , "[MXCrypto] ensureOlmSessionsForDevices: Have already sessions for all" );
1110
1114
if (null != callback ) {
1111
1115
getUIHandler ().post (new Runnable () {
1112
1116
@ Override
@@ -1118,84 +1122,44 @@ public void run() {
1118
1122
return ;
1119
1123
}
1120
1124
1121
- // Prepare the request for claiming one-time keys
1125
+ // Devices for which we will make a /claim request
1122
1126
MXUsersDevicesMap <String > usersDevicesToClaim = new MXUsersDevicesMap <>();
1123
1127
1124
- final String oneTimeKeyAlgorithm = MXKey . KEY_SIGNED_CURVE_25519_TYPE ;
1128
+ Set < String > deviceIdentityKeysWithOlmSessionsInProgress = oneTimeKeysResponseHandler . getDeviceIdentityKeysWithOlmSessionsInProgress () ;
1125
1129
1130
+ // Prepare the request for claiming one-time keys
1126
1131
for (MXDeviceInfo device : devicesWithoutSession ) {
1127
- usersDevicesToClaim .setObject (oneTimeKeyAlgorithm , device .userId , device .deviceId );
1132
+ String deviceIdentityKey = device .identityKey ();
1133
+
1134
+ // Claim only if a request is not yet pending
1135
+ if (!deviceIdentityKeysWithOlmSessionsInProgress .contains (deviceIdentityKey )) {
1136
+ usersDevicesToClaim .setObject (MXKey .KEY_SIGNED_CURVE_25519_TYPE , device .userId , device .deviceId );
1137
+ }
1128
1138
}
1129
1139
1130
- // TODO: this has a race condition - if we try to send another message
1131
- // while we are claiming a key, we will end up claiming two and setting up
1132
- // two sessions.
1133
- //
1134
- // That should eventually resolve itself, but it's poor form.
1140
+ Log .d (LOG_TAG , "[MXCrypto] ensureOlmSessionsForDevices: " + usersDevicesToClaim .getMap ().size ()
1141
+ + " out of " + devicesWithoutSession .size () + " sessions to claim one time keys" );
1135
1142
1136
1143
Log .d (LOG_TAG , "## claimOneTimeKeysForUsersDevices() : " + usersDevicesToClaim );
1137
1144
1145
+ OneTimeKeysResponseHandler .PendingRequest pendingRequest = new OneTimeKeysResponseHandler .PendingRequest (
1146
+ devicesByUser ,
1147
+ callback ,
1148
+ results );
1149
+
1150
+ oneTimeKeysResponseHandler .addPendingRequest (pendingRequest );
1151
+
1152
+ if (usersDevicesToClaim .getMap ().isEmpty ()) {
1153
+ return ;
1154
+ }
1155
+
1138
1156
mCryptoRestClient .claimOneTimeKeysForUsersDevices (usersDevicesToClaim , new ApiCallback <MXUsersDevicesMap <MXKey >>() {
1139
1157
@ Override
1140
1158
public void onSuccess (final MXUsersDevicesMap <MXKey > oneTimeKeys ) {
1141
1159
getEncryptingThreadHandler ().post (new Runnable () {
1142
1160
@ Override
1143
1161
public void run () {
1144
- try {
1145
- Log .d (LOG_TAG , "## claimOneTimeKeysForUsersDevices() : keysClaimResponse.oneTimeKeys: " + oneTimeKeys );
1146
-
1147
- Set <String > userIds = devicesByUser .keySet ();
1148
-
1149
- for (String userId : userIds ) {
1150
- List <MXDeviceInfo > deviceInfos = devicesByUser .get (userId );
1151
-
1152
- for (MXDeviceInfo deviceInfo : deviceInfos ) {
1153
-
1154
- MXKey oneTimeKey = null ;
1155
-
1156
- List <String > deviceIds = oneTimeKeys .getUserDeviceIds (userId );
1157
-
1158
- if (null != deviceIds ) {
1159
- for (String deviceId : deviceIds ) {
1160
- MXOlmSessionResult olmSessionResult = results .getObject (deviceId , userId );
1161
-
1162
- if (null != olmSessionResult .mSessionId ) {
1163
- // We already have a result for this device
1164
- continue ;
1165
- }
1166
-
1167
- MXKey key = oneTimeKeys .getObject (deviceId , userId );
1168
-
1169
- if (TextUtils .equals (key .type , oneTimeKeyAlgorithm )) {
1170
- oneTimeKey = key ;
1171
- }
1172
-
1173
- if (null == oneTimeKey ) {
1174
- Log .d (LOG_TAG , "## ensureOlmSessionsForDevices() : No one-time keys " + oneTimeKeyAlgorithm
1175
- + " for device " + userId + " : " + deviceId );
1176
- continue ;
1177
- }
1178
-
1179
- // Update the result for this device in results
1180
- olmSessionResult .mSessionId = verifyKeyAndStartSession (oneTimeKey , userId , deviceInfo );
1181
- }
1182
- }
1183
- }
1184
- }
1185
- } catch (Exception e ) {
1186
- Log .e (LOG_TAG , "## ensureOlmSessionsForDevices() " + e .getMessage (), e );
1187
- }
1188
-
1189
- if (!hasBeenReleased ()) {
1190
- if (null != callback ) {
1191
- getUIHandler ().post (new Runnable () {
1192
- @ Override
1193
- public void run () {
1194
- callback .onSuccess (results );
1195
- }
1196
- });
1197
- }
1198
- }
1162
+ oneTimeKeysResponseHandler .onOtkRetrieved (oneTimeKeys );
1199
1163
}
1200
1164
});
1201
1165
}
@@ -1204,32 +1168,41 @@ public void run() {
1204
1168
public void onNetworkError (Exception e ) {
1205
1169
Log .e (LOG_TAG , "## ensureOlmSessionsForUsers(): claimOneTimeKeysForUsersDevices request failed" + e .getMessage (), e );
1206
1170
1207
- if (null != callback ) {
1208
- callback .onNetworkError (e );
1209
- }
1171
+ getEncryptingThreadHandler ().post (new Runnable () {
1172
+ @ Override
1173
+ public void run () {
1174
+ oneTimeKeysResponseHandler .onNetworkError (e , usersDevicesToClaim );
1175
+ }
1176
+ });
1210
1177
}
1211
1178
1212
1179
@ Override
1213
1180
public void onMatrixError (MatrixError e ) {
1214
1181
Log .e (LOG_TAG , "## ensureOlmSessionsForUsers(): claimOneTimeKeysForUsersDevices request failed" + e .getMessage ());
1215
1182
1216
- if (null != callback ) {
1217
- callback .onMatrixError (e );
1218
- }
1183
+ getEncryptingThreadHandler ().post (new Runnable () {
1184
+ @ Override
1185
+ public void run () {
1186
+ oneTimeKeysResponseHandler .onMatrixError (e , usersDevicesToClaim );
1187
+ }
1188
+ });
1219
1189
}
1220
1190
1221
1191
@ Override
1222
1192
public void onUnexpectedError (Exception e ) {
1223
1193
Log .e (LOG_TAG , "## ensureOlmSessionsForUsers(): claimOneTimeKeysForUsersDevices request failed" + e .getMessage (), e );
1224
1194
1225
- if (null != callback ) {
1226
- callback .onUnexpectedError (e );
1227
- }
1195
+ getEncryptingThreadHandler ().post (new Runnable () {
1196
+ @ Override
1197
+ public void run () {
1198
+ oneTimeKeysResponseHandler .onUnexpectedError (e , usersDevicesToClaim );
1199
+ }
1200
+ });
1228
1201
}
1229
1202
});
1230
1203
}
1231
1204
1232
- private String verifyKeyAndStartSession (MXKey oneTimeKey , String userId , MXDeviceInfo deviceInfo ) {
1205
+ public String verifyKeyAndStartSession (MXKey oneTimeKey , String userId , MXDeviceInfo deviceInfo ) {
1233
1206
String sessionId = null ;
1234
1207
1235
1208
String deviceId = deviceInfo .deviceId ;
0 commit comments