Search in sources :

Example 1 with RoomMember

use of org.matrix.androidsdk.rest.model.RoomMember in project matrix-android-sdk by matrix-org.

the class MXDataHandler method manageResponse.

/**
 * Manage the sync response in the UI thread.
 *
 * @param syncResponse the syncResponse to manage.
 * @param fromToken    the start sync token
 * @param isCatchingUp true when there is a pending catch-up
 */
private void manageResponse(final SyncResponse syncResponse, final String fromToken, final boolean isCatchingUp) {
    if (!isAlive()) {
        Log.e(LOG_TAG, "manageResponse : ignored because the session has been closed");
        return;
    }
    boolean isInitialSync = (null == fromToken);
    boolean isEmptyResponse = true;
    // sanity check
    if (null != syncResponse) {
        Log.d(LOG_TAG, "onSyncComplete");
        // to ensure to decrypt them properly
        if ((null != syncResponse.toDevice) && (null != syncResponse.toDevice.events) && (syncResponse.toDevice.events.size() > 0)) {
            Log.d(LOG_TAG, "manageResponse : receives " + syncResponse.toDevice.events.size() + " toDevice events");
            for (Event toDeviceEvent : syncResponse.toDevice.events) {
                handleToDeviceEvent(toDeviceEvent);
            }
        }
        // to be able to update direct chats dictionary during invites handling.
        if (null != syncResponse.accountData) {
            Log.d(LOG_TAG, "Received " + syncResponse.accountData.size() + " accountData events");
            manageAccountData(syncResponse.accountData, isInitialSync);
        }
        // sanity check
        if (null != syncResponse.rooms) {
            // joined rooms events
            if ((null != syncResponse.rooms.join) && (syncResponse.rooms.join.size() > 0)) {
                Log.d(LOG_TAG, "Received " + syncResponse.rooms.join.size() + " joined rooms");
                Set<String> roomIds = syncResponse.rooms.join.keySet();
                // Handle first joined rooms
                for (String roomId : roomIds) {
                    try {
                        if (null != mLeftRoomsStore.getRoom(roomId)) {
                            Log.d(LOG_TAG, "the room " + roomId + " moves from left to the joined ones");
                            mLeftRoomsStore.deleteRoom(roomId);
                        }
                        getRoom(roomId).handleJoinedRoomSync(syncResponse.rooms.join.get(roomId), isInitialSync);
                    } catch (Exception e) {
                        Log.e(LOG_TAG, "## manageResponse() : handleJoinedRoomSync failed " + e.getMessage() + " for room " + roomId);
                    }
                }
                isEmptyResponse = false;
            }
            // invited room management
            if ((null != syncResponse.rooms.invite) && (syncResponse.rooms.invite.size() > 0)) {
                Log.d(LOG_TAG, "Received " + syncResponse.rooms.invite.size() + " invited rooms");
                Set<String> roomIds = syncResponse.rooms.invite.keySet();
                HashMap<String, List<String>> updatedDirectChatRoomsDict = null;
                boolean hasChanged = false;
                for (String roomId : roomIds) {
                    try {
                        Log.d(LOG_TAG, "## manageResponse() : the user has been invited to " + roomId);
                        if (null != mLeftRoomsStore.getRoom(roomId)) {
                            Log.d(LOG_TAG, "the room " + roomId + " moves from left to the invited ones");
                            mLeftRoomsStore.deleteRoom(roomId);
                        }
                        Room room = getRoom(roomId);
                        InvitedRoomSync invitedRoomSync = syncResponse.rooms.invite.get(roomId);
                        room.handleInvitedRoomSync(invitedRoomSync);
                        // Handle here the invites to a direct chat.
                        if (room.isDirectChatInvitation()) {
                            // Retrieve the inviter user id.
                            String participantUserId = null;
                            for (Event event : invitedRoomSync.inviteState.events) {
                                if (null != event.sender) {
                                    participantUserId = event.sender;
                                    break;
                                }
                            }
                            if (null != participantUserId) {
                                // Prepare the updated dictionary.
                                if (null == updatedDirectChatRoomsDict) {
                                    if (null != this.getStore().getDirectChatRoomsDict()) {
                                        // Consider the current dictionary.
                                        updatedDirectChatRoomsDict = new HashMap<>(this.getStore().getDirectChatRoomsDict());
                                    } else {
                                        updatedDirectChatRoomsDict = new HashMap<>();
                                    }
                                }
                                ArrayList<String> roomIdsList;
                                if (updatedDirectChatRoomsDict.containsKey(participantUserId)) {
                                    roomIdsList = new ArrayList<>(updatedDirectChatRoomsDict.get(participantUserId));
                                } else {
                                    roomIdsList = new ArrayList<>();
                                }
                                // Check whether the room was not yet seen as direct chat
                                if (roomIdsList.indexOf(roomId) < 0) {
                                    Log.d(LOG_TAG, "## manageResponse() : add this new invite in direct chats");
                                    // update room list with the new room
                                    roomIdsList.add(roomId);
                                    updatedDirectChatRoomsDict.put(participantUserId, roomIdsList);
                                    hasChanged = true;
                                }
                            }
                        }
                    } catch (Exception e) {
                        Log.e(LOG_TAG, "## manageResponse() : handleInvitedRoomSync failed " + e.getMessage() + " for room " + roomId);
                    }
                }
                isEmptyResponse = false;
                if (hasChanged) {
                    mAccountDataRestClient.setAccountData(mCredentials.userId, AccountDataRestClient.ACCOUNT_DATA_TYPE_DIRECT_MESSAGES, updatedDirectChatRoomsDict, new ApiCallback<Void>() {

                        @Override
                        public void onSuccess(Void info) {
                            Log.d(LOG_TAG, "## manageResponse() : succeeds");
                        }

                        @Override
                        public void onNetworkError(Exception e) {
                            Log.e(LOG_TAG, "## manageResponse() : update account data failed " + e.getMessage());
                        // TODO: we should try again.
                        }

                        @Override
                        public void onMatrixError(MatrixError e) {
                            Log.e(LOG_TAG, "## manageResponse() : update account data failed " + e.getMessage());
                        }

                        @Override
                        public void onUnexpectedError(Exception e) {
                            Log.e(LOG_TAG, "## manageResponse() : update account data failed " + e.getMessage());
                        }
                    });
                }
            }
            // when inviting after leaving a room, the room is defined in the both leave & invite rooms list.
            if ((null != syncResponse.rooms.leave) && (syncResponse.rooms.leave.size() > 0)) {
                Log.d(LOG_TAG, "Received " + syncResponse.rooms.leave.size() + " left rooms");
                Set<String> roomIds = syncResponse.rooms.leave.keySet();
                for (String roomId : roomIds) {
                    // RoomSync leftRoomSync = syncResponse.rooms.leave.get(roomId);
                    // Presently we remove the existing room from the rooms list.
                    // FIXME SYNC V2 Archive/Display the left rooms!
                    // For that create 'handleArchivedRoomSync' method
                    String membership = RoomMember.MEMBERSHIP_LEAVE;
                    Room room = getRoom(roomId);
                    // check if the room still exists.
                    if (null != room) {
                        // use 'handleJoinedRoomSync' to pass the last events to the room before leaving it.
                        // The room will then able to notify its listeners.
                        room.handleJoinedRoomSync(syncResponse.rooms.leave.get(roomId), isInitialSync);
                        RoomMember member = room.getMember(getUserId());
                        if (null != member) {
                            membership = member.membership;
                        }
                        Log.d(LOG_TAG, "## manageResponse() : leave the room " + roomId);
                    }
                    if (!TextUtils.equals(membership, RoomMember.MEMBERSHIP_KICK) && !TextUtils.equals(membership, RoomMember.MEMBERSHIP_BAN)) {
                        // ensure that the room data are properly deleted
                        this.getStore().deleteRoom(roomId);
                        onLeaveRoom(roomId);
                    } else {
                        onRoomKick(roomId);
                    }
                    // don't add to the left rooms if the user has been kicked / banned
                    if ((mAreLeftRoomsSynced) && TextUtils.equals(membership, RoomMember.MEMBERSHIP_LEAVE)) {
                        Room leftRoom = getRoom(mLeftRoomsStore, roomId, true);
                        leftRoom.handleJoinedRoomSync(syncResponse.rooms.leave.get(roomId), isInitialSync);
                    }
                }
                isEmptyResponse = false;
            }
        }
        // groups
        if (null != syncResponse.groups) {
            // Handle invited groups
            if ((null != syncResponse.groups.invite) && !syncResponse.groups.invite.isEmpty()) {
                // Handle invited groups
                for (String groupId : syncResponse.groups.invite.keySet()) {
                    InvitedGroupSync invitedGroupSync = syncResponse.groups.invite.get(groupId);
                    mGroupsManager.onNewGroupInvitation(groupId, invitedGroupSync.profile, invitedGroupSync.inviter, !isInitialSync);
                }
            }
            // Handle joined groups
            if ((null != syncResponse.groups.join) && !syncResponse.groups.join.isEmpty()) {
                for (String groupId : syncResponse.groups.join.keySet()) {
                    mGroupsManager.onJoinGroup(groupId, !isInitialSync);
                }
            }
            // Handle left groups
            if ((null != syncResponse.groups.leave) && !syncResponse.groups.leave.isEmpty()) {
                // Handle joined groups
                for (String groupId : syncResponse.groups.leave.keySet()) {
                    mGroupsManager.onLeaveGroup(groupId, !isInitialSync);
                }
            }
        }
        // Handle presence of other users
        if ((null != syncResponse.presence) && (null != syncResponse.presence.events)) {
            Log.d(LOG_TAG, "Received " + syncResponse.presence.events.size() + " presence events");
            for (Event presenceEvent : syncResponse.presence.events) {
                handlePresenceEvent(presenceEvent);
            }
        }
        if (null != mCrypto) {
            mCrypto.onSyncCompleted(syncResponse, fromToken, isCatchingUp);
        }
        IMXStore store = getStore();
        if (!isEmptyResponse && (null != store)) {
            store.setEventStreamToken(syncResponse.nextBatch);
            store.commit();
        }
    }
    if (isInitialSync) {
        if (!isCatchingUp) {
            startCrypto(true);
        } else {
            // the events thread sends a dummy initial sync event
            // when the application is restarted.
            mIsStartingCryptoWithInitialSync = !isEmptyResponse;
        }
        onInitialSyncComplete((null != syncResponse) ? syncResponse.nextBatch : null);
    } else {
        if (!isCatchingUp) {
            startCrypto(mIsStartingCryptoWithInitialSync);
        }
        try {
            onLiveEventsChunkProcessed(fromToken, (null != syncResponse) ? syncResponse.nextBatch : fromToken);
        } catch (Exception e) {
            Log.e(LOG_TAG, "onLiveEventsChunkProcessed failed " + e.getMessage());
        }
        try {
            // check if an incoming call has been received
            mCallsManager.checkPendingIncomingCalls();
        } catch (Exception e) {
            Log.e(LOG_TAG, "checkPendingIncomingCalls failed " + e + " " + e.getMessage());
        }
    }
}
Also used : IMXStore(org.matrix.androidsdk.data.store.IMXStore) InvitedRoomSync(org.matrix.androidsdk.rest.model.sync.InvitedRoomSync) MXDecryptionException(org.matrix.androidsdk.crypto.MXDecryptionException) UnrecognizedCertificateException(org.matrix.androidsdk.ssl.UnrecognizedCertificateException) InvitedGroupSync(org.matrix.androidsdk.rest.model.group.InvitedGroupSync) RoomMember(org.matrix.androidsdk.rest.model.RoomMember) Event(org.matrix.androidsdk.rest.model.Event) List(java.util.List) ArrayList(java.util.ArrayList) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) Room(org.matrix.androidsdk.data.Room)

Example 2 with RoomMember

use of org.matrix.androidsdk.rest.model.RoomMember in project matrix-android-sdk by matrix-org.

the class MXCrypto method setDeviceVerification.

/**
 * Update the blocked/verified state of the given device.
 *
 * @param verificationStatus the new verification status
 * @param deviceId           the unique identifier for the device.
 * @param userId             the owner of the device
 * @param callback           the asynchronous callback
 */
public void setDeviceVerification(final int verificationStatus, final String deviceId, final String userId, final ApiCallback<Void> callback) {
    if (hasBeenReleased()) {
        return;
    }
    final ArrayList<String> userRoomIds = new ArrayList<>();
    Collection<Room> rooms = mSession.getDataHandler().getStore().getRooms();
    for (Room room : rooms) {
        if (room.isEncrypted()) {
            RoomMember roomMember = room.getMember(userId);
            // test if the user joins the room
            if ((null != roomMember) && TextUtils.equals(roomMember.membership, RoomMember.MEMBERSHIP_JOIN)) {
                userRoomIds.add(room.getRoomId());
            }
        }
    }
    getEncryptingThreadHandler().post(new Runnable() {

        @Override
        public void run() {
            MXDeviceInfo device = mCryptoStore.getUserDevice(deviceId, userId);
            // Sanity check
            if (null == device) {
                Log.e(LOG_TAG, "## setDeviceVerification() : Unknown device " + userId + ":" + deviceId);
                if (null != callback) {
                    getUIHandler().post(new Runnable() {

                        @Override
                        public void run() {
                            callback.onSuccess(null);
                        }
                    });
                }
                return;
            }
            if (device.mVerified != verificationStatus) {
                device.mVerified = verificationStatus;
                mCryptoStore.storeUserDevice(userId, device);
            }
            if (null != callback) {
                getUIHandler().post(new Runnable() {

                    @Override
                    public void run() {
                        callback.onSuccess(null);
                    }
                });
            }
        }
    });
}
Also used : RoomMember(org.matrix.androidsdk.rest.model.RoomMember) MXDeviceInfo(org.matrix.androidsdk.crypto.data.MXDeviceInfo) ArrayList(java.util.ArrayList) Room(org.matrix.androidsdk.data.Room)

Example 3 with RoomMember

use of org.matrix.androidsdk.rest.model.RoomMember in project matrix-android-sdk by matrix-org.

the class MXCrypto method setEncryptionInRoom.

/**
 * Configure a room to use encryption.
 * This method must be called in getEncryptingThreadHandler
 *
 * @param roomId             the room id to enable encryption in.
 * @param algorithm          the encryption config for the room.
 * @param inhibitDeviceQuery true to suppress device list query for users in the room (for now)
 * @return true if the operation succeeds.
 */
private boolean setEncryptionInRoom(String roomId, String algorithm, boolean inhibitDeviceQuery) {
    if (hasBeenReleased()) {
        return false;
    }
    // If we already have encryption in this room, we should ignore this event
    // (for now at least. Maybe we should alert the user somehow?)
    String existingAlgorithm = mCryptoStore.getRoomAlgorithm(roomId);
    if (!TextUtils.isEmpty(existingAlgorithm) && !TextUtils.equals(existingAlgorithm, algorithm)) {
        Log.e(LOG_TAG, "## setEncryptionInRoom() : Ignoring m.room.encryption event which requests a change of config in " + roomId);
        return false;
    }
    Class<IMXEncrypting> encryptingClass = MXCryptoAlgorithms.sharedAlgorithms().encryptorClassForAlgorithm(algorithm);
    if (null == encryptingClass) {
        Log.e(LOG_TAG, "## setEncryptionInRoom() : Unable to encrypt with " + algorithm);
        return false;
    }
    mCryptoStore.storeRoomAlgorithm(roomId, algorithm);
    IMXEncrypting alg;
    try {
        Constructor<?> ctor = encryptingClass.getConstructors()[0];
        alg = (IMXEncrypting) ctor.newInstance();
    } catch (Exception e) {
        Log.e(LOG_TAG, "## setEncryptionInRoom() : fail to load the class");
        return false;
    }
    alg.initWithMatrixSession(mSession, roomId);
    synchronized (mRoomEncryptors) {
        mRoomEncryptors.put(roomId, alg);
    }
    // we just invalidate everyone in the room.
    if (null == existingAlgorithm) {
        Log.d(LOG_TAG, "Enabling encryption in " + roomId + " for the first time; invalidating device lists for all users therein");
        Room room = mSession.getDataHandler().getRoom(roomId);
        if (null != room) {
            Collection<RoomMember> members = room.getJoinedMembers();
            List<String> userIds = new ArrayList<>();
            for (RoomMember m : members) {
                userIds.add(m.getUserId());
            }
            getDeviceList().startTrackingDeviceList(userIds);
            if (!inhibitDeviceQuery) {
                getDeviceList().refreshOutdatedDeviceLists();
            }
        }
    }
    return true;
}
Also used : IMXEncrypting(org.matrix.androidsdk.crypto.algorithms.IMXEncrypting) RoomMember(org.matrix.androidsdk.rest.model.RoomMember) ArrayList(java.util.ArrayList) Room(org.matrix.androidsdk.data.Room)

Example 4 with RoomMember

use of org.matrix.androidsdk.rest.model.RoomMember in project matrix-android-sdk by matrix-org.

the class MXCallsManager method inviteConferenceUser.

/**
 * Invite the conference user to a room.
 * It is mandatory before starting a conference call.
 *
 * @param room     the room
 * @param callback the async callback
 */
private void inviteConferenceUser(final Room room, final ApiCallback<Void> callback) {
    Log.d(LOG_TAG, "inviteConferenceUser " + room.getRoomId());
    String conferenceUserId = getConferenceUserId(room.getRoomId());
    RoomMember conferenceMember = room.getMember(conferenceUserId);
    if ((null != conferenceMember) && TextUtils.equals(conferenceMember.membership, RoomMember.MEMBERSHIP_JOIN)) {
        mUIThreadHandler.post(new Runnable() {

            @Override
            public void run() {
                callback.onSuccess(null);
            }
        });
    } else {
        room.invite(conferenceUserId, callback);
    }
}
Also used : RoomMember(org.matrix.androidsdk.rest.model.RoomMember)

Example 5 with RoomMember

use of org.matrix.androidsdk.rest.model.RoomMember in project matrix-android-sdk by matrix-org.

the class RoomState method getMemberName.

/**
 * Return an unique display name of the member userId.
 *
 * @param userId the user id
 * @return unique display name
 */
public String getMemberName(String userId) {
    // sanity check
    if (null == userId) {
        return null;
    }
    String displayName;
    synchronized (this) {
        if (null == mMemberDisplayNameByUserId) {
            mMemberDisplayNameByUserId = new HashMap<>();
        }
        displayName = mMemberDisplayNameByUserId.get(userId);
    }
    if (null != displayName) {
        return displayName;
    }
    // Get the user display name from the member list of the room
    RoomMember member = getMember(userId);
    // Do not consider null display name
    if ((null != member) && !TextUtils.isEmpty(member.displayname)) {
        displayName = member.displayname;
        synchronized (this) {
            ArrayList<String> matrixIds = new ArrayList<>();
            // Disambiguate users who have the same display name in the room
            for (RoomMember aMember : mMembers.values()) {
                if (displayName.equals(aMember.displayname)) {
                    matrixIds.add(aMember.getUserId());
                }
            }
            // index it i.e bob (<Matrix id>)
            if (matrixIds.size() > 1) {
                displayName += " (" + userId + ")";
            }
        }
    } else if ((null != member) && TextUtils.equals(member.membership, RoomMember.MEMBERSHIP_INVITE)) {
        User user = ((MXDataHandler) mDataHandler).getUser(userId);
        if (null != user) {
            displayName = user.displayname;
        }
    }
    if (null == displayName) {
        // By default, use the user ID
        displayName = userId;
    }
    mMemberDisplayNameByUserId.put(userId, displayName);
    return displayName;
}
Also used : User(org.matrix.androidsdk.rest.model.User) RoomMember(org.matrix.androidsdk.rest.model.RoomMember) ArrayList(java.util.ArrayList)

Aggregations

RoomMember (org.matrix.androidsdk.rest.model.RoomMember)35 ArrayList (java.util.ArrayList)20 Room (org.matrix.androidsdk.data.Room)12 Event (org.matrix.androidsdk.rest.model.Event)6 MatrixError (org.matrix.androidsdk.rest.model.MatrixError)6 HashMap (java.util.HashMap)4 HashSet (java.util.HashSet)3 List (java.util.List)3 Map (java.util.Map)3 IMXEncrypting (org.matrix.androidsdk.crypto.algorithms.IMXEncrypting)3 ApiCallback (org.matrix.androidsdk.rest.callback.ApiCallback)3 HandlerThread (android.os.HandlerThread)2 JsonObject (com.google.gson.JsonObject)2 Iterator (java.util.Iterator)2 Set (java.util.Set)2 MXDecryptionException (org.matrix.androidsdk.crypto.MXDecryptionException)2 IMXStore (org.matrix.androidsdk.data.store.IMXStore)2 SimpleApiCallback (org.matrix.androidsdk.rest.callback.SimpleApiCallback)2 RoomThirdPartyInvite (org.matrix.androidsdk.rest.model.pid.RoomThirdPartyInvite)2 UnrecognizedCertificateException (org.matrix.androidsdk.ssl.UnrecognizedCertificateException)2