Search in sources :

Example 56 with Room

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;
}
Also used : Room(org.matrix.androidsdk.data.Room) File(java.io.File) RoomState(org.matrix.androidsdk.data.RoomState)

Example 57 with Room

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

Example 58 with Room

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;
}
Also used : Event(org.matrix.androidsdk.rest.model.Event) File(java.io.File) Room(org.matrix.androidsdk.data.Room)

Example 59 with Room

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);
}
Also used : File(java.io.File) Room(org.matrix.androidsdk.data.Room)

Example 60 with Room

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;
}
Also used : MyUser(org.matrix.androidsdk.data.MyUser) Message(org.matrix.androidsdk.rest.model.message.Message) Room(org.matrix.androidsdk.data.Room) BingRule(org.matrix.androidsdk.rest.model.bingrules.BingRule)

Aggregations

Room (org.matrix.androidsdk.data.Room)60 MatrixError (org.matrix.androidsdk.rest.model.MatrixError)33 Event (org.matrix.androidsdk.rest.model.Event)27 ArrayList (java.util.ArrayList)26 CountDownLatch (java.util.concurrent.CountDownLatch)26 HashMap (java.util.HashMap)25 JsonObject (com.google.gson.JsonObject)24 Test (org.junit.Test)22 RoomState (org.matrix.androidsdk.data.RoomState)22 MXEventListener (org.matrix.androidsdk.listeners.MXEventListener)19 Context (android.content.Context)15 RoomMember (org.matrix.androidsdk.rest.model.RoomMember)12 EventTimeline (org.matrix.androidsdk.data.EventTimeline)8 IMXStore (org.matrix.androidsdk.data.store.IMXStore)8 File (java.io.File)7 MXDeviceInfo (org.matrix.androidsdk.crypto.data.MXDeviceInfo)6 ApiCallback (org.matrix.androidsdk.rest.callback.ApiCallback)6 Credentials (org.matrix.androidsdk.rest.model.login.Credentials)6 List (java.util.List)5 Uri (android.net.Uri)4