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;
}
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);
}
}
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;
}
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;
}
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();
}
}
Aggregations