Search in sources :

Example 16 with MXUsersDevicesMap

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);
            }
        }
    });
}
Also used : HashMap(java.util.HashMap) MXOlmSessionResult(org.matrix.androidsdk.crypto.data.MXOlmSessionResult) MXDeviceInfo(org.matrix.androidsdk.crypto.data.MXDeviceInfo) MXUsersDevicesMap(org.matrix.androidsdk.crypto.data.MXUsersDevicesMap) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) HashMap(java.util.HashMap) MXUsersDevicesMap(org.matrix.androidsdk.crypto.data.MXUsersDevicesMap) Map(java.util.Map)

Aggregations

MXUsersDevicesMap (org.matrix.androidsdk.crypto.data.MXUsersDevicesMap)16 MXDeviceInfo (org.matrix.androidsdk.crypto.data.MXDeviceInfo)13 MatrixError (org.matrix.androidsdk.rest.model.MatrixError)13 HashMap (java.util.HashMap)12 CountDownLatch (java.util.concurrent.CountDownLatch)8 Test (org.junit.Test)7 Context (android.content.Context)6 JsonObject (com.google.gson.JsonObject)6 ArrayList (java.util.ArrayList)5 Map (java.util.Map)4 MXOlmSessionResult (org.matrix.androidsdk.crypto.data.MXOlmSessionResult)4 MXEventListener (org.matrix.androidsdk.listeners.MXEventListener)4 MXCryptoError (org.matrix.androidsdk.crypto.MXCryptoError)3 MXKey (org.matrix.androidsdk.crypto.data.MXKey)3 Room (org.matrix.androidsdk.data.Room)3 KeysUploadResponse (org.matrix.androidsdk.rest.model.crypto.KeysUploadResponse)3 Uri (android.net.Uri)2 MXOlmInboundGroupSession2 (org.matrix.androidsdk.crypto.data.MXOlmInboundGroupSession2)2 RoomState (org.matrix.androidsdk.data.RoomState)2 IMXStore (org.matrix.androidsdk.data.store.IMXStore)2