use of org.matrix.androidsdk.crypto.data.MXUsersDevicesMap in project matrix-android-sdk by matrix-org.
the class MXMegolmEncryption method shareUserDevicesKey.
/**
* Share the device keys of a an user
*
* @param session the session info
* @param devicesByUser the devices map
* @param callback the asynchronous callback
*/
private void shareUserDevicesKey(final MXOutboundSessionInfo session, final HashMap<String, ArrayList<MXDeviceInfo>> devicesByUser, final ApiCallback<Void> callback) {
final String sessionKey = mCrypto.getOlmDevice().getSessionKey(session.mSessionId);
final int chainIndex = mCrypto.getOlmDevice().getMessageIndex(session.mSessionId);
HashMap<String, Object> submap = new HashMap<>();
submap.put("algorithm", MXCryptoAlgorithms.MXCRYPTO_ALGORITHM_MEGOLM);
submap.put("room_id", mRoomId);
submap.put("session_id", session.mSessionId);
submap.put("session_key", sessionKey);
submap.put("chain_index", chainIndex);
final HashMap<String, Object> payload = new HashMap<>();
payload.put("type", Event.EVENT_TYPE_ROOM_KEY);
payload.put("content", submap);
final long t0 = System.currentTimeMillis();
Log.d(LOG_TAG, "## shareUserDevicesKey() : starts");
mCrypto.ensureOlmSessionsForDevices(devicesByUser, new ApiCallback<MXUsersDevicesMap<MXOlmSessionResult>>() {
@Override
public void onSuccess(final MXUsersDevicesMap<MXOlmSessionResult> results) {
mCrypto.getEncryptingThreadHandler().post(new Runnable() {
@Override
public void run() {
Log.d(LOG_TAG, "## shareUserDevicesKey() : ensureOlmSessionsForDevices succeeds after " + (System.currentTimeMillis() - t0) + " ms");
MXUsersDevicesMap<Map<String, Object>> contentMap = new MXUsersDevicesMap<>();
boolean haveTargets = false;
List<String> userIds = results.getUserIds();
for (String userId : userIds) {
ArrayList<MXDeviceInfo> devicesToShareWith = devicesByUser.get(userId);
for (MXDeviceInfo deviceInfo : devicesToShareWith) {
String deviceID = deviceInfo.deviceId;
MXOlmSessionResult sessionResult = results.getObject(deviceID, userId);
if ((null == sessionResult) || (null == sessionResult.mSessionId)) {
// so just skip it.
continue;
}
Log.d(LOG_TAG, "## shareUserDevicesKey() : Sharing keys with device " + userId + ":" + deviceID);
// noinspection ArraysAsListWithZeroOrOneArgument,ArraysAsListWithZeroOrOneArgument
contentMap.setObject(mCrypto.encryptMessage(payload, Arrays.asList(sessionResult.mDevice)), userId, deviceID);
haveTargets = true;
}
}
if (haveTargets && !mCrypto.hasBeenReleased()) {
final long t0 = System.currentTimeMillis();
Log.d(LOG_TAG, "## shareUserDevicesKey() : has target");
mSession.getCryptoRestClient().sendToDevice(Event.EVENT_TYPE_MESSAGE_ENCRYPTED, contentMap, new ApiCallback<Void>() {
@Override
public void onSuccess(Void info) {
mCrypto.getEncryptingThreadHandler().post(new Runnable() {
@Override
public void run() {
Log.d(LOG_TAG, "## shareUserDevicesKey() : sendToDevice succeeds after " + (System.currentTimeMillis() - t0) + " ms");
// for dead devices on every message.
for (String userId : devicesByUser.keySet()) {
List<MXDeviceInfo> devicesToShareWith = devicesByUser.get(userId);
for (MXDeviceInfo deviceInfo : devicesToShareWith) {
session.mSharedWithDevices.setObject(chainIndex, userId, deviceInfo.deviceId);
}
}
mCrypto.getUIHandler().post(new Runnable() {
@Override
public void run() {
if (null != callback) {
callback.onSuccess(null);
}
}
});
}
});
}
@Override
public void onNetworkError(Exception e) {
Log.d(LOG_TAG, "## shareUserDevicesKey() : sendToDevice onNetworkError " + e.getMessage());
if (null != callback) {
callback.onNetworkError(e);
}
}
@Override
public void onMatrixError(MatrixError e) {
Log.d(LOG_TAG, "## shareUserDevicesKey() : sendToDevice onMatrixError " + e.getMessage());
if (null != callback) {
callback.onMatrixError(e);
}
}
@Override
public void onUnexpectedError(Exception e) {
Log.d(LOG_TAG, "## shareUserDevicesKey() : sendToDevice onUnexpectedError " + e.getMessage());
if (null != callback) {
callback.onUnexpectedError(e);
}
}
});
} else {
Log.d(LOG_TAG, "## shareUserDevicesKey() : no need to sharekey");
if (null != callback) {
mCrypto.getUIHandler().post(new Runnable() {
@Override
public void run() {
callback.onSuccess(null);
}
});
}
}
}
});
}
@Override
public void onNetworkError(Exception e) {
Log.d(LOG_TAG, "## shareUserDevicesKey() : ensureOlmSessionsForDevices failed " + e.getMessage());
if (null != callback) {
callback.onNetworkError(e);
}
}
@Override
public void onMatrixError(MatrixError e) {
Log.d(LOG_TAG, "## shareUserDevicesKey() : ensureOlmSessionsForDevices failed " + e.getMessage());
if (null != callback) {
callback.onMatrixError(e);
}
}
@Override
public void onUnexpectedError(Exception e) {
Log.d(LOG_TAG, "## shareUserDevicesKey() : ensureOlmSessionsForDevices failed " + e.getMessage());
if (null != callback) {
callback.onUnexpectedError(e);
}
}
});
}
Aggregations