Search in sources :

Example 26 with RoomMember

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

the class RoomState method applyState.

/**
 * Apply the given event (relevant for state changes) to our state.
 *
 * @param store     the store to use
 * @param event     the event
 * @param direction how the event should affect the state: Forwards for applying, backwards for un-applying (applying the previous state)
 * @return true if the event is managed
 */
public boolean applyState(IMXStore store, Event event, EventTimeline.Direction direction) {
    if (event.stateKey == null) {
        return false;
    }
    JsonObject contentToConsider = (direction == EventTimeline.Direction.FORWARDS) ? event.getContentAsJsonObject() : event.getPrevContentAsJsonObject();
    String eventType = event.getType();
    try {
        if (Event.EVENT_TYPE_STATE_ROOM_NAME.equals(eventType)) {
            name = JsonUtils.toRoomState(contentToConsider).name;
        } else if (Event.EVENT_TYPE_STATE_ROOM_TOPIC.equals(eventType)) {
            topic = JsonUtils.toRoomState(contentToConsider).topic;
        } else if (Event.EVENT_TYPE_STATE_ROOM_CREATE.equals(eventType)) {
            creator = JsonUtils.toRoomState(contentToConsider).creator;
        } else if (Event.EVENT_TYPE_STATE_ROOM_JOIN_RULES.equals(eventType)) {
            join_rule = JsonUtils.toRoomState(contentToConsider).join_rule;
        } else if (Event.EVENT_TYPE_STATE_ROOM_GUEST_ACCESS.equals(eventType)) {
            guest_access = JsonUtils.toRoomState(contentToConsider).guest_access;
        } else if (Event.EVENT_TYPE_STATE_ROOM_ALIASES.equals(eventType)) {
            if (!TextUtils.isEmpty(event.stateKey)) {
                // backward compatibility
                aliases = JsonUtils.toRoomState(contentToConsider).aliases;
                // sanity check
                if (null != aliases) {
                    mAliasesByDomain.put(event.stateKey, aliases);
                    mRoomAliases.put(event.stateKey, event);
                } else {
                    mAliasesByDomain.put(event.stateKey, new ArrayList<String>());
                }
            }
        } else if (Event.EVENT_TYPE_MESSAGE_ENCRYPTION.equals(eventType)) {
            algorithm = JsonUtils.toRoomState(contentToConsider).algorithm;
            // This flag should not be cleared if a later m.room.encryption event changes the configuration. This is to avoid a situation where a MITM can simply ask participants to disable encryption. In short: once encryption is enabled in a room, it can never be disabled.
            if (null == algorithm) {
                algorithm = "";
            }
        } else if (Event.EVENT_TYPE_STATE_CANONICAL_ALIAS.equals(eventType)) {
            // SPEC-125
            alias = JsonUtils.toRoomState(contentToConsider).alias;
        } else if (Event.EVENT_TYPE_STATE_HISTORY_VISIBILITY.equals(eventType)) {
            // SPEC-134
            history_visibility = JsonUtils.toRoomState(contentToConsider).history_visibility;
        } else if (Event.EVENT_TYPE_STATE_ROOM_AVATAR.equals(eventType)) {
            url = JsonUtils.toRoomState(contentToConsider).url;
        } else if (Event.EVENT_TYPE_STATE_RELATED_GROUPS.equals(eventType)) {
            groups = JsonUtils.toRoomState(contentToConsider).groups;
        } else if (Event.EVENT_TYPE_STATE_ROOM_MEMBER.equals(eventType)) {
            RoomMember member = JsonUtils.toRoomMember(contentToConsider);
            String userId = event.stateKey;
            if (null == userId) {
                Log.e(LOG_TAG, "## applyState() : null stateKey in " + roomId);
            } else if (null == member) {
                // the member has already been removed
                if (null == getMember(userId)) {
                    Log.e(LOG_TAG, "## applyState() : the user " + userId + " is not anymore a member of " + roomId);
                    return false;
                }
                removeMember(userId);
            } else {
                try {
                    member.setUserId(userId);
                    member.setOriginServerTs(event.getOriginServerTs());
                    member.setOriginalEventId(event.eventId);
                    member.mSender = event.getSender();
                    if ((null != store) && (direction == EventTimeline.Direction.FORWARDS)) {
                        store.storeRoomStateEvent(roomId, event);
                    }
                    RoomMember currentMember = getMember(userId);
                    // duplicated message ?
                    if (member.equals(currentMember)) {
                        Log.e(LOG_TAG, "## applyState() : seems being a duplicated event for " + userId + " in room " + roomId);
                        return false;
                    }
                    // when a member leaves a room, his avatar / display name is not anymore provided
                    if (null != currentMember) {
                        if (TextUtils.equals(member.membership, RoomMember.MEMBERSHIP_LEAVE) || TextUtils.equals(member.membership, (RoomMember.MEMBERSHIP_BAN))) {
                            if (null == member.getAvatarUrl()) {
                                member.setAvatarUrl(currentMember.getAvatarUrl());
                            }
                            if (null == member.displayname) {
                                member.displayname = currentMember.displayname;
                            }
                            // remove the cached display name
                            if (null != mMemberDisplayNameByUserId) {
                                mMemberDisplayNameByUserId.remove(userId);
                            }
                            // test if the user has been kicked
                            if (!TextUtils.equals(event.getSender(), event.stateKey) && TextUtils.equals(currentMember.membership, RoomMember.MEMBERSHIP_JOIN) && TextUtils.equals(member.membership, RoomMember.MEMBERSHIP_LEAVE)) {
                                member.membership = RoomMember.MEMBERSHIP_KICK;
                            }
                        }
                    }
                    if ((direction == EventTimeline.Direction.FORWARDS) && (null != store)) {
                        store.updateUserWithRoomMemberEvent(member);
                    }
                    // Cache room member event that is successor of a third party invite event
                    if (!TextUtils.isEmpty(member.getThirdPartyInviteToken())) {
                        mMembersWithThirdPartyInviteTokenCache.put(member.getThirdPartyInviteToken(), member);
                    }
                } catch (Exception e) {
                    Log.e(LOG_TAG, "## applyState() - EVENT_TYPE_STATE_ROOM_MEMBER failed " + e.getMessage());
                }
                setMember(userId, member);
            }
        } else if (Event.EVENT_TYPE_STATE_ROOM_POWER_LEVELS.equals(eventType)) {
            powerLevels = JsonUtils.toPowerLevels(contentToConsider);
        } else if (Event.EVENT_TYPE_STATE_ROOM_THIRD_PARTY_INVITE.equals(event.getType())) {
            if (null != contentToConsider) {
                RoomThirdPartyInvite thirdPartyInvite = JsonUtils.toRoomThirdPartyInvite(contentToConsider);
                thirdPartyInvite.token = event.stateKey;
                if ((direction == EventTimeline.Direction.FORWARDS) && (null != store)) {
                    store.storeRoomStateEvent(roomId, event);
                }
                if (!TextUtils.isEmpty(thirdPartyInvite.token)) {
                    mThirdPartyInvites.put(thirdPartyInvite.token, thirdPartyInvite);
                }
            }
        }
        // they are saved elsewhere
        if (!TextUtils.isEmpty(eventType) && !Event.EVENT_TYPE_STATE_ROOM_MEMBER.equals(eventType)) {
            List<Event> eventsList = mStateEvents.get(eventType);
            if (null == eventsList) {
                eventsList = new ArrayList<>();
                mStateEvents.put(eventType, eventsList);
            }
            eventsList.add(event);
        }
    } catch (Exception e) {
        Log.e(LOG_TAG, "applyState failed with error " + e.getMessage());
    }
    return true;
}
Also used : RoomThirdPartyInvite(org.matrix.androidsdk.rest.model.pid.RoomThirdPartyInvite) RoomMember(org.matrix.androidsdk.rest.model.RoomMember) ArrayList(java.util.ArrayList) JsonObject(com.google.gson.JsonObject) Event(org.matrix.androidsdk.rest.model.Event) IOException(java.io.IOException)

Example 27 with RoomMember

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

the class RoomState method isConferenceUserRoom.

/**
 * Tells if the room is a call conference one
 * i.e. this room has been created to manage the call conference
 *
 * @return true if it is a call conference room.
 */
public boolean isConferenceUserRoom() {
    // test if it is not yet initialized
    if (null == mIsConferenceUserRoom) {
        mIsConferenceUserRoom = false;
        Collection<RoomMember> members = getMembers();
        // works only with 1:1 room
        if (2 == members.size()) {
            for (RoomMember member : members) {
                if (MXCallsManager.isConferenceUserId(member.getUserId())) {
                    mIsConferenceUserRoom = true;
                    break;
                }
            }
        }
    }
    return mIsConferenceUserRoom;
}
Also used : RoomMember(org.matrix.androidsdk.rest.model.RoomMember)

Example 28 with RoomMember

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

the class RoomState method canBackPaginated.

/**
 * Check if the user userId can back paginate.
 *
 * @param userId the user Id.
 * @return true if the user can backpaginate.
 */
public boolean canBackPaginated(String userId) {
    RoomMember member = getMember(userId);
    String membership = (null != member) ? member.membership : "";
    String visibility = TextUtils.isEmpty(history_visibility) ? HISTORY_VISIBILITY_SHARED : history_visibility;
    return visibility.equals(HISTORY_VISIBILITY_WORLD_READABLE) || visibility.equals(HISTORY_VISIBILITY_SHARED) || (RoomMember.MEMBERSHIP_JOIN.equals(membership)) || /*&&visibility == invited or joined */
    (RoomMember.MEMBERSHIP_INVITE.equals(membership) && visibility.equals(HISTORY_VISIBILITY_INVITED));
}
Also used : RoomMember(org.matrix.androidsdk.rest.model.RoomMember)

Example 29 with RoomMember

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

the class RoomState method deepCopy.

/**
 * Make a deep copy of this room state object.
 *
 * @return the copy
 */
public RoomState deepCopy() {
    RoomState copy = new RoomState();
    copy.roomId = roomId;
    copy.setPowerLevels((powerLevels == null) ? null : powerLevels.deepCopy());
    copy.aliases = (aliases == null) ? null : new ArrayList<>(aliases);
    copy.mAliasesByDomain = new HashMap<>(mAliasesByDomain);
    copy.alias = this.alias;
    copy.name = name;
    copy.topic = topic;
    copy.url = url;
    copy.creator = creator;
    copy.join_rule = join_rule;
    copy.guest_access = guest_access;
    copy.history_visibility = history_visibility;
    copy.visibility = visibility;
    copy.roomAliasName = roomAliasName;
    copy.token = token;
    copy.groups = groups;
    copy.mDataHandler = mDataHandler;
    copy.mMembership = mMembership;
    copy.mIsLive = mIsLive;
    copy.mIsConferenceUserRoom = mIsConferenceUserRoom;
    copy.algorithm = algorithm;
    copy.mRoomAliases = new HashMap<>(mRoomAliases);
    copy.mStateEvents = new HashMap<>(mStateEvents);
    synchronized (this) {
        Iterator it = mMembers.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, RoomMember> pair = (Map.Entry<String, RoomMember>) it.next();
            copy.setMember(pair.getKey(), pair.getValue().deepCopy());
        }
        Collection<String> keys = mThirdPartyInvites.keySet();
        for (String key : keys) {
            copy.mThirdPartyInvites.put(key, mThirdPartyInvites.get(key).deepCopy());
        }
        keys = mMembersWithThirdPartyInviteTokenCache.keySet();
        for (String key : keys) {
            copy.mMembersWithThirdPartyInviteTokenCache.put(key, mMembersWithThirdPartyInviteTokenCache.get(key).deepCopy());
        }
    }
    return copy;
}
Also used : RoomMember(org.matrix.androidsdk.rest.model.RoomMember) ArrayList(java.util.ArrayList) Iterator(java.util.Iterator) HashMap(java.util.HashMap) Map(java.util.Map)

Example 30 with RoomMember

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

the class MXFileStore method open.

/**
 * Open the store.
 */
@Override
public void open() {
    super.open();
    final long fLoadTimeT0 = System.currentTimeMillis();
    // avoid concurrency call.
    synchronized (this) {
        if (!mIsReady && !mIsOpening && (null != mMetadata) && (null != mHandlerThread)) {
            mIsOpening = true;
            Log.e(LOG_TAG, "Open the store.");
            // creation the background handler.
            if (null == mFileStoreHandler) {
                // never succeeded to reproduce but it was reported in GA.
                try {
                    mHandlerThread.start();
                } catch (IllegalThreadStateException e) {
                    Log.e(LOG_TAG, "mHandlerThread is already started.");
                    // already started
                    return;
                }
                mFileStoreHandler = new MXOsHandler(mHandlerThread.getLooper());
            }
            Runnable r = new Runnable() {

                @Override
                public void run() {
                    mFileStoreHandler.post(new Runnable() {

                        public void run() {
                            Log.e(LOG_TAG, "Open the store in the background thread.");
                            String errorDescription = null;
                            boolean succeed = (mMetadata.mVersion == MXFILE_VERSION) && TextUtils.equals(mMetadata.mUserId, mCredentials.userId) && TextUtils.equals(mMetadata.mAccessToken, mCredentials.accessToken);
                            if (!succeed) {
                                errorDescription = "Invalid store content";
                                Log.e(LOG_TAG, errorDescription);
                            }
                            if (succeed) {
                                succeed &= loadRoomsMessages();
                                if (!succeed) {
                                    errorDescription = "loadRoomsMessages fails";
                                    Log.e(LOG_TAG, errorDescription);
                                } else {
                                    Log.e(LOG_TAG, "loadRoomsMessages succeeds");
                                }
                            }
                            if (succeed) {
                                succeed &= loadGroups();
                                if (!succeed) {
                                    errorDescription = "loadGroups fails";
                                    Log.e(LOG_TAG, errorDescription);
                                } else {
                                    Log.e(LOG_TAG, "loadGroups succeeds");
                                }
                            }
                            if (succeed) {
                                succeed &= loadRoomsState();
                                if (!succeed) {
                                    errorDescription = "loadRoomsState fails";
                                    Log.e(LOG_TAG, errorDescription);
                                } else {
                                    Log.e(LOG_TAG, "loadRoomsState succeeds");
                                    long t0 = System.currentTimeMillis();
                                    Log.e(LOG_TAG, "Retrieve the users from the roomstate");
                                    Collection<Room> rooms = getRooms();
                                    for (Room room : rooms) {
                                        Collection<RoomMember> members = room.getLiveState().getMembers();
                                        for (RoomMember member : members) {
                                            updateUserWithRoomMemberEvent(member);
                                        }
                                    }
                                    long delta = System.currentTimeMillis() - t0;
                                    Log.e(LOG_TAG, "Retrieve " + mUsers.size() + " users with the room states in " + delta + "  ms");
                                    mStoreStats.put("Retrieve users", delta);
                                }
                            }
                            if (succeed) {
                                succeed &= loadSummaries();
                                if (!succeed) {
                                    errorDescription = "loadSummaries fails";
                                    Log.e(LOG_TAG, errorDescription);
                                } else {
                                    Log.e(LOG_TAG, "loadSummaries succeeds");
                                    for (String roomId : mRoomSummaries.keySet()) {
                                        Room room = getRoom(roomId);
                                        if (null == room) {
                                            succeed = false;
                                            Log.e(LOG_TAG, "loadSummaries : the room " + roomId + " does not exist");
                                        } else if (null == room.getMember(mCredentials.userId)) {
                                            // succeed = false;
                                            Log.e(LOG_TAG, "loadSummaries) : a summary exists for the roomId " + roomId + " but the user is not anymore a member");
                                        }
                                    }
                                }
                            }
                            if (succeed) {
                                succeed &= loadRoomsAccountData();
                                if (!succeed) {
                                    errorDescription = "loadRoomsAccountData fails";
                                    Log.e(LOG_TAG, errorDescription);
                                } else {
                                    Log.e(LOG_TAG, "loadRoomsAccountData succeeds");
                                }
                            }
                            // assume that something is corrupted
                            if (!succeed) {
                                Log.e(LOG_TAG, "Fail to open the store in background");
                                // delete all data set mMetadata to null
                                // backup it to restore it
                                // the behaviour should be the same as first login
                                MXFileStoreMetaData tmpMetadata = mMetadata;
                                deleteAllData(true);
                                mRoomsToCommitForMessages = new HashSet<>();
                                mRoomsToCommitForStates = new HashSet<>();
                                // mRoomsToCommitForStatesEvents = new HashSet<>();
                                mRoomsToCommitForSummaries = new HashSet<>();
                                mRoomsToCommitForReceipts = new HashSet<>();
                                mMetadata = tmpMetadata;
                                // mMetadata should only be null at file store loading
                                if (null == mMetadata) {
                                    mMetadata = new MXFileStoreMetaData();
                                    mMetadata.mUserId = mCredentials.userId;
                                    mMetadata.mAccessToken = mCredentials.accessToken;
                                    mMetaDataHasChanged = true;
                                } else {
                                    mMetadata.mEventStreamToken = null;
                                }
                                mMetadata.mVersion = MXFILE_VERSION;
                                // the event stream token is put to zero to ensure ta
                                mEventStreamToken = null;
                                mAreReceiptsReady = true;
                            } else {
                                Log.d(LOG_TAG, "++ store stats");
                                Set<String> roomIds = mRoomEvents.keySet();
                                for (String roomId : roomIds) {
                                    Room room = getRoom(roomId);
                                    if ((null != room) && (null != room.getLiveState())) {
                                        int membersCount = room.getLiveState().getMembers().size();
                                        int eventsCount = mRoomEvents.get(roomId).size();
                                        Log.d(LOG_TAG, " room " + roomId + " : membersCount " + membersCount + " - eventsCount " + eventsCount);
                                    }
                                }
                                Log.d(LOG_TAG, "-- store stats");
                            }
                            // post processing
                            Log.d(LOG_TAG, "## open() : post processing.");
                            dispatchPostProcess(mCredentials.userId);
                            mIsPostProcessingDone = true;
                            synchronized (this) {
                                mIsReady = true;
                            }
                            mIsOpening = false;
                            if (!succeed && !mIsNewStorage) {
                                Log.e(LOG_TAG, "The store is corrupted.");
                                dispatchOnStoreCorrupted(mCredentials.userId, errorDescription);
                            } else {
                                // extract the room states
                                mRoomReceiptsToLoad.addAll(listFiles(mStoreRoomsMessagesReceiptsFolderFile.list()));
                                mPreloadTime = System.currentTimeMillis() - fLoadTimeT0;
                                Log.e(LOG_TAG, "The store is opened.");
                                dispatchOnStoreReady(mCredentials.userId);
                                // load the following items with delay
                                // theses items are not required to be ready
                                // load the receipts
                                loadReceipts();
                                // load the users
                                loadUsers();
                            }
                        }
                    });
                }
            };
            Thread t = new Thread(r);
            t.start();
        } else if (mIsReady) {
            Runnable r = new Runnable() {

                @Override
                public void run() {
                    mFileStoreHandler.post(new Runnable() {

                        @Override
                        public void run() {
                            // should never happen
                            if (!mIsPostProcessingDone && !mIsNewStorage) {
                                Log.e(LOG_TAG, "## open() : is ready but the post processing was not yet done : please wait....");
                                return;
                            } else {
                                if (!mIsPostProcessingDone) {
                                    Log.e(LOG_TAG, "## open() : is ready but the post processing was not yet done.");
                                    dispatchPostProcess(mCredentials.userId);
                                    mIsPostProcessingDone = true;
                                } else {
                                    Log.e(LOG_TAG, "## open() when ready : the post processing is already done.");
                                }
                                dispatchOnStoreReady(mCredentials.userId);
                                mPreloadTime = System.currentTimeMillis() - fLoadTimeT0;
                            }
                        }
                    });
                }
            };
            Thread t = new Thread(r);
            t.start();
        }
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) MXOsHandler(org.matrix.androidsdk.util.MXOsHandler) HandlerThread(android.os.HandlerThread) RoomMember(org.matrix.androidsdk.rest.model.RoomMember) Collection(java.util.Collection) Room(org.matrix.androidsdk.data.Room) HashSet(java.util.HashSet)

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