use of org.matrix.androidsdk.data.Room in project matrix-android-sdk by matrix-org.
the class MXFileStore method loadRoomState.
/**
* Load a room state from the file system.
*
* @param roomId the room id.
* @return true if the operation succeeds.
*/
private boolean loadRoomState(final String roomId) {
boolean succeed = true;
Room room = getRoom(roomId);
// should always be true
if (null != room) {
RoomState liveState = null;
try {
// the room state is not zipped
File roomStateFile = new File(mGzStoreRoomsStateFolderFile, roomId);
// new format
if (roomStateFile.exists()) {
Object roomStateAsObject = readObject("loadRoomState " + roomId, roomStateFile);
if (null == roomStateAsObject) {
succeed = false;
} else {
liveState = (RoomState) roomStateAsObject;
}
}
} catch (Exception e) {
succeed = false;
Log.e(LOG_TAG, "loadRoomState failed : " + e.getMessage());
}
if (null != liveState) {
room.getLiveTimeLine().setState(liveState);
} else {
deleteRoom(roomId);
}
} else {
try {
File messagesListFile = new File(mGzStoreRoomsStateFolderFile, roomId);
messagesListFile.delete();
} catch (Exception e) {
Log.e(LOG_TAG, "loadRoomState failed to delete a file : " + e.getMessage());
}
}
return succeed;
}
use of org.matrix.androidsdk.data.Room 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();
}
}
}
use of org.matrix.androidsdk.data.Room 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.data.Room in project matrix-android-sdk by matrix-org.
the class MXFileStore method saveRoomState.
/**
* Save the room state.
*
* @param roomId the room id.
*/
private void saveRoomState(final String roomId) {
Log.d(LOG_TAG, "++ saveRoomsState " + roomId);
File roomStateFile = new File(mGzStoreRoomsStateFolderFile, roomId);
Room room = mRooms.get(roomId);
if (null != room) {
long start1 = System.currentTimeMillis();
writeObject("saveRoomsState " + roomId, roomStateFile, room.getState());
Log.d(LOG_TAG, "saveRoomsState " + room.getState().getMembers().size() + " members : " + (System.currentTimeMillis() - start1) + " ms");
} else {
Log.d(LOG_TAG, "saveRoomsState : delete the room state");
deleteRoomStateFile(roomId);
}
Log.d(LOG_TAG, "-- saveRoomsState " + roomId);
}
use of org.matrix.androidsdk.data.Room in project matrix-android-sdk by matrix-org.
the class BingRulesManager method fulfilledBingRule.
/**
* Returns the first notifiable bing rule which fulfills its condition with this event.
*
* @param event the event
* @param highlightRuleOnly true to only check the highlight rule
* @return the first matched bing rule, null if none
*/
private BingRule fulfilledBingRule(Event event, boolean highlightRuleOnly) {
// sanity check
if (null == event) {
Log.e(LOG_TAG, "## fulfilledBingRule() : null event");
return null;
}
if (!mIsInitialized) {
Log.e(LOG_TAG, "## fulfilledBingRule() : not initialized");
return null;
}
if (0 == mRules.size()) {
Log.e(LOG_TAG, "## fulfilledBingRule() : no rules");
return null;
}
// do not trigger notification for oneself messages
if ((null != event.getSender()) && TextUtils.equals(event.getSender(), mMyUserId)) {
return null;
}
String eventType = event.getType();
// some types are not bingable
if (TextUtils.equals(eventType, Event.EVENT_TYPE_PRESENCE) || TextUtils.equals(eventType, Event.EVENT_TYPE_TYPING) || TextUtils.equals(eventType, Event.EVENT_TYPE_REDACTION) || TextUtils.equals(eventType, Event.EVENT_TYPE_RECEIPT) || TextUtils.equals(eventType, Event.EVENT_TYPE_TAGS)) {
return null;
}
// GA issue
final ArrayList<BingRule> rules;
synchronized (this) {
rules = new ArrayList<>(mRules);
}
// Go down the rule list until we find a match
for (BingRule bingRule : rules) {
if (bingRule.isEnabled && (!highlightRuleOnly || bingRule.shouldHighlight())) {
boolean isFullfilled = false;
// so their ruleId defines the method
if (BingRule.RULE_ID_CONTAIN_USER_NAME.equals(bingRule.ruleId) || BingRule.RULE_ID_CONTAIN_DISPLAY_NAME.equals(bingRule.ruleId)) {
if (Event.EVENT_TYPE_MESSAGE.equals(event.getType())) {
Message message = JsonUtils.toMessage(event.getContent());
MyUser myUser = mSession.getMyUser();
String pattern = null;
if (BingRule.RULE_ID_CONTAIN_USER_NAME.equals(bingRule.ruleId)) {
if (mMyUserId.indexOf(":") >= 0) {
pattern = mMyUserId.substring(1, mMyUserId.indexOf(":"));
} else {
pattern = mMyUserId;
}
} else if (BingRule.RULE_ID_CONTAIN_DISPLAY_NAME.equals(bingRule.ruleId)) {
pattern = myUser.displayname;
if ((null != mSession.getDataHandler()) && (null != mSession.getDataHandler().getStore())) {
Room room = mSession.getDataHandler().getStore().getRoom(event.roomId);
if ((null != room) && (null != room.getLiveState())) {
String disambiguousedName = room.getLiveState().getMemberName(mMyUserId);
if (!TextUtils.equals(disambiguousedName, mMyUserId)) {
pattern = Pattern.quote(disambiguousedName);
}
}
}
}
if (!TextUtils.isEmpty(pattern)) {
isFullfilled = caseInsensitiveFind(pattern, message.body);
}
}
} else if (BingRule.RULE_ID_FALLBACK.equals(bingRule.ruleId)) {
isFullfilled = true;
} else {
// some default rules define conditions
// so use them instead of doing a custom treatment
// RULE_ID_ONE_TO_ONE_ROOM
// RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS
isFullfilled = eventMatchesConditions(event, bingRule.conditions);
}
if (isFullfilled) {
return bingRule;
}
}
}
// no rules are fulfilled
return null;
}
Aggregations