Search in sources :

Example 66 with Event

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

the class MXFileStore method loadRoomMessages.

/**
 * Load room messages from the filesystem.
 *
 * @param roomId the room id.
 * @return true if succeed.
 */
private boolean loadRoomMessages(final String roomId) {
    boolean succeeded = true;
    boolean shouldSave = false;
    LinkedHashMap<String, Event> events = null;
    File messagesListFile = new File(mGzStoreRoomsMessagesFolderFile, roomId);
    if (messagesListFile.exists()) {
        Object eventsAsVoid = readObject("events " + roomId, messagesListFile);
        if (null != eventsAsVoid) {
            try {
                events = (LinkedHashMap<String, Event>) eventsAsVoid;
            } catch (Exception e) {
                Log.e(LOG_TAG, "loadRoomMessages " + roomId + "failed : " + e.getMessage());
                return false;
            }
            if (events.size() > (2 * MAX_STORED_MESSAGES_COUNT)) {
                Log.d(LOG_TAG, "## loadRoomMessages() : the room " + roomId + " has " + events.size() + " stored events : we need to find a way to reduce it.");
            }
            // finalizes the deserialization
            for (Event event : events.values()) {
                // if a message was not sent, mark at as UNDELIVERABLE
                if ((event.mSentState == Event.SentState.UNDELIVERABLE) || (event.mSentState == Event.SentState.UNSENT) || (event.mSentState == Event.SentState.SENDING) || (event.mSentState == Event.SentState.WAITING_RETRY) || (event.mSentState == Event.SentState.ENCRYPTING)) {
                    event.mSentState = Event.SentState.UNDELIVERABLE;
                    shouldSave = true;
                }
            }
        } else {
            return false;
        }
    }
    // succeeds to extract the message list
    if (null != events) {
        // create the room object
        Room room = new Room();
        room.init(this, roomId, null);
        // do not wait that the live state update
        room.setReadyState(true);
        storeRoom(room);
        mRoomEvents.put(roomId, events);
    }
    if (shouldSave) {
        saveRoomMessages(roomId);
    }
    return succeeded;
}
Also used : Event(org.matrix.androidsdk.rest.model.Event) File(java.io.File) Room(org.matrix.androidsdk.data.Room)

Example 67 with Event

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

the class MXMemoryStore method storeLiveRoomEvent.

@Override
public void storeLiveRoomEvent(Event event) {
    try {
        if ((null != event) && (null != event.roomId) && (null != event.eventId)) {
            synchronized (mRoomEventsLock) {
                LinkedHashMap<String, Event> events = mRoomEvents.get(event.roomId);
                // create the list it does not exist
                if (null == events) {
                    events = new LinkedHashMap<>();
                    mRoomEvents.put(event.roomId, events);
                } else if (events.containsKey(event.eventId)) {
                    // the event is already define
                    return;
                } else if (!event.isDummyEvent() && (mTemporaryEventsList.size() > 0)) {
                    // remove any waiting echo event
                    String dummyKey = null;
                    for (String key : mTemporaryEventsList.keySet()) {
                        Event eventToCheck = mTemporaryEventsList.get(key);
                        if (TextUtils.equals(eventToCheck.eventId, event.eventId)) {
                            dummyKey = key;
                            break;
                        }
                    }
                    if (null != dummyKey) {
                        events.remove(dummyKey);
                        mTemporaryEventsList.remove(dummyKey);
                    }
                }
                // If we don't have any information on this room - a pagination token, namely - we don't store the event but instead
                // wait for the first pagination request to set things right
                events.put(event.eventId, event);
                if (event.isDummyEvent()) {
                    mTemporaryEventsList.put(event.eventId, event);
                }
            }
        }
    } catch (OutOfMemoryError e) {
        dispatchOOM(e);
    }
}
Also used : Event(org.matrix.androidsdk.rest.model.Event)

Example 68 with Event

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

the class MXMemoryStore method getEarlierMessages.

@Override
public TokensChunkResponse<Event> getEarlierMessages(final String roomId, final String fromToken, final int limit) {
    // For older requests (providing a token), returning null for now
    if (null != roomId) {
        ArrayList<Event> eventsList;
        synchronized (mRoomEventsLock) {
            LinkedHashMap<String, Event> events = mRoomEvents.get(roomId);
            if ((events == null) || (events.size() == 0)) {
                return null;
            }
            // reach the end of the stored items
            if (TextUtils.equals(mRoomTokens.get(roomId), fromToken)) {
                return null;
            }
            // check if the token is known in the sublist
            eventsList = new ArrayList<>(events.values());
        }
        ArrayList<Event> subEventsList = new ArrayList<>();
        // search from the latest to the oldest events
        Collections.reverse(eventsList);
        TokensChunkResponse<Event> response = new TokensChunkResponse<>();
        // start the latest event and there is enough events to provide to the caller ?
        if ((null == fromToken) && (eventsList.size() <= limit)) {
            subEventsList = eventsList;
        } else {
            int index = 0;
            if (null != fromToken) {
                // search if token is one of the stored events
                for (; (index < eventsList.size()) && (!TextUtils.equals(fromToken, eventsList.get(index).mToken)); index++) ;
                index++;
            }
            // found it ?
            if (index < eventsList.size()) {
                for (; index < eventsList.size(); index++) {
                    Event event = eventsList.get(index);
                    subEventsList.add(event);
                    // loop until to find an event with a token
                    if ((subEventsList.size() >= limit) && (event.mToken != null)) {
                        break;
                    }
                }
            }
        }
        // unknown token
        if (subEventsList.size() == 0) {
            return null;
        }
        response.chunk = subEventsList;
        Event firstEvent = subEventsList.get(0);
        Event lastEvent = subEventsList.get(subEventsList.size() - 1);
        response.start = firstEvent.mToken;
        // unknown last event token, use the latest known one
        if ((null == lastEvent.mToken) && !TextUtils.isEmpty(mRoomTokens.get(roomId))) {
            lastEvent.mToken = mRoomTokens.get(roomId);
        }
        response.end = lastEvent.mToken;
        return response;
    }
    return null;
}
Also used : TokensChunkResponse(org.matrix.androidsdk.rest.model.TokensChunkResponse) ArrayList(java.util.ArrayList) Event(org.matrix.androidsdk.rest.model.Event)

Example 69 with Event

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

the class EventTimeline method manageBackEvents.

/**
 * Send MAX_EVENT_COUNT_PER_PAGINATION events to the caller.
 *
 * @param maxEventCount the max event count
 * @param callback      the callback.
 */
private void manageBackEvents(int maxEventCount, final ApiCallback<Integer> callback) {
    // check if the SDK was not logged out
    if (!mDataHandler.isAlive()) {
        Log.d(LOG_TAG, "manageEvents : mDataHandler is not anymore active.");
        return;
    }
    int count = Math.min(mSnapshotEvents.size(), maxEventCount);
    Event latestSupportedEvent = null;
    for (int i = 0; i < count; i++) {
        SnapshotEvent snapshotedEvent = mSnapshotEvents.get(0);
        // https://github.com/vector-im/vector-android/pull/354
        if ((null == latestSupportedEvent) && RoomSummary.isSupportedEvent(snapshotedEvent.mEvent)) {
            latestSupportedEvent = snapshotedEvent.mEvent;
        }
        mSnapshotEvents.remove(0);
        onEvent(snapshotedEvent.mEvent, Direction.BACKWARDS, snapshotedEvent.mState);
    }
    // https://github.com/vector-im/vector-android/pull/354
    // defines a new summary if the known is not supported
    RoomSummary summary = mStore.getSummary(mRoomId);
    if ((null != latestSupportedEvent) && ((null == summary) || !RoomSummary.isSupportedEvent(summary.getLatestReceivedEvent()))) {
        mStore.storeSummary(new RoomSummary(null, latestSupportedEvent, mState, mDataHandler.getUserId()));
    }
    Log.d(LOG_TAG, "manageEvents : commit");
    mStore.commit();
    if ((mSnapshotEvents.size() < MAX_EVENT_COUNT_PER_PAGINATION) && mIsLastBackChunk) {
        mCanBackPaginate = false;
    }
    if (callback != null) {
        try {
            callback.onSuccess(count);
        } catch (Exception e) {
            Log.e(LOG_TAG, "requestHistory exception " + e.getMessage());
        }
    }
    mIsBackPaginating = false;
}
Also used : Event(org.matrix.androidsdk.rest.model.Event)

Example 70 with Event

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

the class EventTimeline method addPaginationEvents.

/**
 * Add some events in a dedicated direction.
 *
 * @param events    the events list
 * @param direction the direction
 */
private void addPaginationEvents(List<Event> events, Direction direction) {
    RoomSummary summary = mStore.getSummary(mRoomId);
    boolean shouldCommitStore = false;
    // the backward events have a dedicated management to avoid providing too many events for each request
    for (Event event : events) {
        boolean processedEvent = true;
        if (event.stateKey != null) {
            deepCopyState(direction);
            processedEvent = processStateEvent(event, direction);
        }
        // Decrypt event if necessary
        mDataHandler.decryptEvent(event, getTimelineId());
        if (processedEvent) {
            // it should avoid duplicated events.
            if (direction == Direction.BACKWARDS) {
                if (mIsLiveTimeline) {
                    // it might happen after a timeline update (hole in the chat history)
                    if ((null != summary) && ((null == summary.getLatestReceivedEvent()) || (event.isValidOriginServerTs() && (summary.getLatestReceivedEvent().originServerTs < event.originServerTs) && RoomSummary.isSupportedEvent(event)))) {
                        summary.setLatestReceivedEvent(event, getState());
                        mStore.storeSummary(summary);
                        shouldCommitStore = true;
                    }
                }
                mSnapshotEvents.add(new SnapshotEvent(event, getBackState()));
            // onEvent will be called in manageBackEvents
            }
        }
    }
    if (shouldCommitStore) {
        mStore.commit();
    }
}
Also used : Event(org.matrix.androidsdk.rest.model.Event)

Aggregations

Event (org.matrix.androidsdk.rest.model.Event)73 ArrayList (java.util.ArrayList)31 JsonObject (com.google.gson.JsonObject)28 Room (org.matrix.androidsdk.data.Room)27 MatrixError (org.matrix.androidsdk.rest.model.MatrixError)27 HashMap (java.util.HashMap)23 CountDownLatch (java.util.concurrent.CountDownLatch)22 RoomState (org.matrix.androidsdk.data.RoomState)21 Test (org.junit.Test)20 MXEventListener (org.matrix.androidsdk.listeners.MXEventListener)19 Context (android.content.Context)14 MotionEvent (android.view.MotionEvent)9 EventTimeline (org.matrix.androidsdk.data.EventTimeline)9 IMXStore (org.matrix.androidsdk.data.store.IMXStore)7 ReceiptData (org.matrix.androidsdk.rest.model.ReceiptData)6 RoomMember (org.matrix.androidsdk.rest.model.RoomMember)6 Credentials (org.matrix.androidsdk.rest.model.login.Credentials)6 Uri (android.net.Uri)5 File (java.io.File)4 MessageRow (org.matrix.androidsdk.adapters.MessageRow)4