Search in sources :

Example 16 with MatrixError

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

the class CryptoTestHelper method createAccountAndSync.

/**
 * Create an account and a dedicated session
 * @param context the context
 * @param userName the account username
 * @param password the password
 * @param startSession true to perform an initial sync
 * @throws Exception an exception if the account creation failed
 */
public static MXSession createAccountAndSync(Context context, String userName, String password, boolean startSession) throws Exception {
    Uri uri = Uri.parse(TESTS_HOME_SERVER_URL);
    HomeServerConnectionConfig hs = new HomeServerConnectionConfig(uri);
    LoginRestClient loginRestClient = new LoginRestClient(hs);
    final HashMap<String, Object> params = new HashMap<>();
    RegistrationParams registrationParams = new RegistrationParams();
    mLock = new CountDownLatch(1);
    // get the registration session id
    loginRestClient.register(registrationParams, new ApiCallback<Credentials>() {

        @Override
        public void onSuccess(Credentials credentials) {
            mLock.countDown();
        }

        @Override
        public void onNetworkError(Exception e) {
            mLock.countDown();
        }

        @Override
        public void onMatrixError(MatrixError e) {
            // detect if a parameter is expected
            RegistrationFlowResponse registrationFlowResponse = null;
            // when a response is not completed the server returns an error message
            if ((null != e.mStatus) && (e.mStatus == 401)) {
                try {
                    registrationFlowResponse = JsonUtils.toRegistrationFlowResponse(e.mErrorBodyAsString);
                } catch (Exception castExcept) {
                }
            }
            // check if the server response can be casted
            if (null != registrationFlowResponse) {
                params.put("session", registrationFlowResponse.session);
            }
            mLock.countDown();
        }

        @Override
        public void onUnexpectedError(Exception e) {
            mLock.countDown();
        }
    });
    mLock.await(10000, TimeUnit.MILLISECONDS);
    String session = (String) params.get("session");
    assertTrue(null != session);
    registrationParams.username = userName;
    registrationParams.password = password;
    HashMap<String, Object> authParams = new HashMap<>();
    authParams.put("session", session);
    authParams.put("type", LoginRestClient.LOGIN_FLOW_TYPE_DUMMY);
    registrationParams.auth = authParams;
    mLock = new CountDownLatch(1);
    loginRestClient.register(registrationParams, new ApiCallback<Credentials>() {

        @Override
        public void onSuccess(Credentials credentials) {
            params.put("credentials", credentials);
            mLock.countDown();
        }

        @Override
        public void onNetworkError(Exception e) {
            mLock.countDown();
        }

        @Override
        public void onMatrixError(MatrixError e) {
            mLock.countDown();
        }

        @Override
        public void onUnexpectedError(Exception e) {
            mLock.countDown();
        }
    });
    mLock.await(10000, TimeUnit.MILLISECONDS);
    Credentials credentials = (Credentials) params.get("credentials");
    assertTrue(null != credentials);
    hs.setCredentials(credentials);
    IMXStore store = new MXFileStore(hs, context);
    MXSession mxSession = new MXSession(hs, new MXDataHandler(store, credentials), context);
    if (!startSession) {
        return mxSession;
    }
    mxSession.getDataHandler().getStore().open();
    mxSession.startEventStream(null);
    mLock = new CountDownLatch(1);
    mxSession.getDataHandler().addListener(new MXEventListener() {

        @Override
        public void onInitialSyncComplete(String toToken) {
            params.put("isInit", true);
            mLock.countDown();
        }
    });
    mLock.await(100000, TimeUnit.MILLISECONDS);
    assertTrue(params.containsKey("isInit"));
    return mxSession;
}
Also used : HashMap(java.util.HashMap) RegistrationFlowResponse(org.matrix.androidsdk.rest.model.login.RegistrationFlowResponse) IMXStore(org.matrix.androidsdk.data.store.IMXStore) MXFileStore(org.matrix.androidsdk.data.store.MXFileStore) CountDownLatch(java.util.concurrent.CountDownLatch) Uri(android.net.Uri) MXEventListener(org.matrix.androidsdk.listeners.MXEventListener) RegistrationParams(org.matrix.androidsdk.rest.model.login.RegistrationParams) LoginRestClient(org.matrix.androidsdk.rest.client.LoginRestClient) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) Credentials(org.matrix.androidsdk.rest.model.login.Credentials)

Example 17 with MatrixError

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

the class MXDataHandler method manageResponse.

/**
 * Manage the sync response in the UI thread.
 *
 * @param syncResponse the syncResponse to manage.
 * @param fromToken    the start sync token
 * @param isCatchingUp true when there is a pending catch-up
 */
private void manageResponse(final SyncResponse syncResponse, final String fromToken, final boolean isCatchingUp) {
    if (!isAlive()) {
        Log.e(LOG_TAG, "manageResponse : ignored because the session has been closed");
        return;
    }
    boolean isInitialSync = (null == fromToken);
    boolean isEmptyResponse = true;
    // sanity check
    if (null != syncResponse) {
        Log.d(LOG_TAG, "onSyncComplete");
        // to ensure to decrypt them properly
        if ((null != syncResponse.toDevice) && (null != syncResponse.toDevice.events) && (syncResponse.toDevice.events.size() > 0)) {
            Log.d(LOG_TAG, "manageResponse : receives " + syncResponse.toDevice.events.size() + " toDevice events");
            for (Event toDeviceEvent : syncResponse.toDevice.events) {
                handleToDeviceEvent(toDeviceEvent);
            }
        }
        // to be able to update direct chats dictionary during invites handling.
        if (null != syncResponse.accountData) {
            Log.d(LOG_TAG, "Received " + syncResponse.accountData.size() + " accountData events");
            manageAccountData(syncResponse.accountData, isInitialSync);
        }
        // sanity check
        if (null != syncResponse.rooms) {
            // joined rooms events
            if ((null != syncResponse.rooms.join) && (syncResponse.rooms.join.size() > 0)) {
                Log.d(LOG_TAG, "Received " + syncResponse.rooms.join.size() + " joined rooms");
                Set<String> roomIds = syncResponse.rooms.join.keySet();
                // Handle first joined rooms
                for (String roomId : roomIds) {
                    try {
                        if (null != mLeftRoomsStore.getRoom(roomId)) {
                            Log.d(LOG_TAG, "the room " + roomId + " moves from left to the joined ones");
                            mLeftRoomsStore.deleteRoom(roomId);
                        }
                        getRoom(roomId).handleJoinedRoomSync(syncResponse.rooms.join.get(roomId), isInitialSync);
                    } catch (Exception e) {
                        Log.e(LOG_TAG, "## manageResponse() : handleJoinedRoomSync failed " + e.getMessage() + " for room " + roomId);
                    }
                }
                isEmptyResponse = false;
            }
            // invited room management
            if ((null != syncResponse.rooms.invite) && (syncResponse.rooms.invite.size() > 0)) {
                Log.d(LOG_TAG, "Received " + syncResponse.rooms.invite.size() + " invited rooms");
                Set<String> roomIds = syncResponse.rooms.invite.keySet();
                HashMap<String, List<String>> updatedDirectChatRoomsDict = null;
                boolean hasChanged = false;
                for (String roomId : roomIds) {
                    try {
                        Log.d(LOG_TAG, "## manageResponse() : the user has been invited to " + roomId);
                        if (null != mLeftRoomsStore.getRoom(roomId)) {
                            Log.d(LOG_TAG, "the room " + roomId + " moves from left to the invited ones");
                            mLeftRoomsStore.deleteRoom(roomId);
                        }
                        Room room = getRoom(roomId);
                        InvitedRoomSync invitedRoomSync = syncResponse.rooms.invite.get(roomId);
                        room.handleInvitedRoomSync(invitedRoomSync);
                        // Handle here the invites to a direct chat.
                        if (room.isDirectChatInvitation()) {
                            // Retrieve the inviter user id.
                            String participantUserId = null;
                            for (Event event : invitedRoomSync.inviteState.events) {
                                if (null != event.sender) {
                                    participantUserId = event.sender;
                                    break;
                                }
                            }
                            if (null != participantUserId) {
                                // Prepare the updated dictionary.
                                if (null == updatedDirectChatRoomsDict) {
                                    if (null != this.getStore().getDirectChatRoomsDict()) {
                                        // Consider the current dictionary.
                                        updatedDirectChatRoomsDict = new HashMap<>(this.getStore().getDirectChatRoomsDict());
                                    } else {
                                        updatedDirectChatRoomsDict = new HashMap<>();
                                    }
                                }
                                ArrayList<String> roomIdsList;
                                if (updatedDirectChatRoomsDict.containsKey(participantUserId)) {
                                    roomIdsList = new ArrayList<>(updatedDirectChatRoomsDict.get(participantUserId));
                                } else {
                                    roomIdsList = new ArrayList<>();
                                }
                                // Check whether the room was not yet seen as direct chat
                                if (roomIdsList.indexOf(roomId) < 0) {
                                    Log.d(LOG_TAG, "## manageResponse() : add this new invite in direct chats");
                                    // update room list with the new room
                                    roomIdsList.add(roomId);
                                    updatedDirectChatRoomsDict.put(participantUserId, roomIdsList);
                                    hasChanged = true;
                                }
                            }
                        }
                    } catch (Exception e) {
                        Log.e(LOG_TAG, "## manageResponse() : handleInvitedRoomSync failed " + e.getMessage() + " for room " + roomId);
                    }
                }
                isEmptyResponse = false;
                if (hasChanged) {
                    mAccountDataRestClient.setAccountData(mCredentials.userId, AccountDataRestClient.ACCOUNT_DATA_TYPE_DIRECT_MESSAGES, updatedDirectChatRoomsDict, new ApiCallback<Void>() {

                        @Override
                        public void onSuccess(Void info) {
                            Log.d(LOG_TAG, "## manageResponse() : succeeds");
                        }

                        @Override
                        public void onNetworkError(Exception e) {
                            Log.e(LOG_TAG, "## manageResponse() : update account data failed " + e.getMessage());
                        // TODO: we should try again.
                        }

                        @Override
                        public void onMatrixError(MatrixError e) {
                            Log.e(LOG_TAG, "## manageResponse() : update account data failed " + e.getMessage());
                        }

                        @Override
                        public void onUnexpectedError(Exception e) {
                            Log.e(LOG_TAG, "## manageResponse() : update account data failed " + e.getMessage());
                        }
                    });
                }
            }
            // when inviting after leaving a room, the room is defined in the both leave & invite rooms list.
            if ((null != syncResponse.rooms.leave) && (syncResponse.rooms.leave.size() > 0)) {
                Log.d(LOG_TAG, "Received " + syncResponse.rooms.leave.size() + " left rooms");
                Set<String> roomIds = syncResponse.rooms.leave.keySet();
                for (String roomId : roomIds) {
                    // RoomSync leftRoomSync = syncResponse.rooms.leave.get(roomId);
                    // Presently we remove the existing room from the rooms list.
                    // FIXME SYNC V2 Archive/Display the left rooms!
                    // For that create 'handleArchivedRoomSync' method
                    String membership = RoomMember.MEMBERSHIP_LEAVE;
                    Room room = getRoom(roomId);
                    // check if the room still exists.
                    if (null != room) {
                        // use 'handleJoinedRoomSync' to pass the last events to the room before leaving it.
                        // The room will then able to notify its listeners.
                        room.handleJoinedRoomSync(syncResponse.rooms.leave.get(roomId), isInitialSync);
                        RoomMember member = room.getMember(getUserId());
                        if (null != member) {
                            membership = member.membership;
                        }
                        Log.d(LOG_TAG, "## manageResponse() : leave the room " + roomId);
                    }
                    if (!TextUtils.equals(membership, RoomMember.MEMBERSHIP_KICK) && !TextUtils.equals(membership, RoomMember.MEMBERSHIP_BAN)) {
                        // ensure that the room data are properly deleted
                        this.getStore().deleteRoom(roomId);
                        onLeaveRoom(roomId);
                    } else {
                        onRoomKick(roomId);
                    }
                    // don't add to the left rooms if the user has been kicked / banned
                    if ((mAreLeftRoomsSynced) && TextUtils.equals(membership, RoomMember.MEMBERSHIP_LEAVE)) {
                        Room leftRoom = getRoom(mLeftRoomsStore, roomId, true);
                        leftRoom.handleJoinedRoomSync(syncResponse.rooms.leave.get(roomId), isInitialSync);
                    }
                }
                isEmptyResponse = false;
            }
        }
        // groups
        if (null != syncResponse.groups) {
            // Handle invited groups
            if ((null != syncResponse.groups.invite) && !syncResponse.groups.invite.isEmpty()) {
                // Handle invited groups
                for (String groupId : syncResponse.groups.invite.keySet()) {
                    InvitedGroupSync invitedGroupSync = syncResponse.groups.invite.get(groupId);
                    mGroupsManager.onNewGroupInvitation(groupId, invitedGroupSync.profile, invitedGroupSync.inviter, !isInitialSync);
                }
            }
            // Handle joined groups
            if ((null != syncResponse.groups.join) && !syncResponse.groups.join.isEmpty()) {
                for (String groupId : syncResponse.groups.join.keySet()) {
                    mGroupsManager.onJoinGroup(groupId, !isInitialSync);
                }
            }
            // Handle left groups
            if ((null != syncResponse.groups.leave) && !syncResponse.groups.leave.isEmpty()) {
                // Handle joined groups
                for (String groupId : syncResponse.groups.leave.keySet()) {
                    mGroupsManager.onLeaveGroup(groupId, !isInitialSync);
                }
            }
        }
        // Handle presence of other users
        if ((null != syncResponse.presence) && (null != syncResponse.presence.events)) {
            Log.d(LOG_TAG, "Received " + syncResponse.presence.events.size() + " presence events");
            for (Event presenceEvent : syncResponse.presence.events) {
                handlePresenceEvent(presenceEvent);
            }
        }
        if (null != mCrypto) {
            mCrypto.onSyncCompleted(syncResponse, fromToken, isCatchingUp);
        }
        IMXStore store = getStore();
        if (!isEmptyResponse && (null != store)) {
            store.setEventStreamToken(syncResponse.nextBatch);
            store.commit();
        }
    }
    if (isInitialSync) {
        if (!isCatchingUp) {
            startCrypto(true);
        } else {
            // the events thread sends a dummy initial sync event
            // when the application is restarted.
            mIsStartingCryptoWithInitialSync = !isEmptyResponse;
        }
        onInitialSyncComplete((null != syncResponse) ? syncResponse.nextBatch : null);
    } else {
        if (!isCatchingUp) {
            startCrypto(mIsStartingCryptoWithInitialSync);
        }
        try {
            onLiveEventsChunkProcessed(fromToken, (null != syncResponse) ? syncResponse.nextBatch : fromToken);
        } catch (Exception e) {
            Log.e(LOG_TAG, "onLiveEventsChunkProcessed failed " + e.getMessage());
        }
        try {
            // check if an incoming call has been received
            mCallsManager.checkPendingIncomingCalls();
        } catch (Exception e) {
            Log.e(LOG_TAG, "checkPendingIncomingCalls failed " + e + " " + e.getMessage());
        }
    }
}
Also used : IMXStore(org.matrix.androidsdk.data.store.IMXStore) InvitedRoomSync(org.matrix.androidsdk.rest.model.sync.InvitedRoomSync) MXDecryptionException(org.matrix.androidsdk.crypto.MXDecryptionException) UnrecognizedCertificateException(org.matrix.androidsdk.ssl.UnrecognizedCertificateException) InvitedGroupSync(org.matrix.androidsdk.rest.model.group.InvitedGroupSync) RoomMember(org.matrix.androidsdk.rest.model.RoomMember) Event(org.matrix.androidsdk.rest.model.Event) List(java.util.List) ArrayList(java.util.ArrayList) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) Room(org.matrix.androidsdk.data.Room)

Example 18 with MatrixError

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

the class MXSession method markRoomsAsRead.

/**
 * Send the read receipts to the latest room messages.
 *
 * @param roomsIterator the rooms list iterator
 * @param callback      the asynchronous callback
 */
private void markRoomsAsRead(final Iterator roomsIterator, final ApiCallback<Void> callback) {
    if (roomsIterator.hasNext()) {
        Room room = (Room) roomsIterator.next();
        boolean isRequestSent = false;
        if (mNetworkConnectivityReceiver.isConnected()) {
            isRequestSent = room.markAllAsRead(new ApiCallback<Void>() {

                @Override
                public void onSuccess(Void anything) {
                    markRoomsAsRead(roomsIterator, callback);
                }

                @Override
                public void onNetworkError(Exception e) {
                    if (null != callback) {
                        callback.onNetworkError(e);
                    }
                }

                @Override
                public void onMatrixError(MatrixError e) {
                    if (null != callback) {
                        callback.onMatrixError(e);
                    }
                }

                @Override
                public void onUnexpectedError(Exception e) {
                    if (null != callback) {
                        callback.onUnexpectedError(e);
                    }
                }
            });
        } else {
            // update the local data
            room.sendReadReceipt();
        }
        if (!isRequestSent) {
            markRoomsAsRead(roomsIterator, callback);
        }
    } else {
        if (null != callback) {
            new Handler(Looper.getMainLooper()).post(new Runnable() {

                @Override
                public void run() {
                    callback.onSuccess(null);
                }
            });
        }
    }
}
Also used : ApiCallback(org.matrix.androidsdk.rest.callback.ApiCallback) SimpleApiCallback(org.matrix.androidsdk.rest.callback.SimpleApiCallback) Handler(android.os.Handler) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) Room(org.matrix.androidsdk.data.Room)

Example 19 with MatrixError

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

the class MXDeviceList method doKeyDownloadForUsers.

/**
 * Download the devices keys for a set of users.
 * It must be called in getEncryptingThreadHandler() thread.
 * The callback is called in the UI thread.
 *
 * @param downloadUsers the user ids list
 * @param callback      the asynchronous callback
 */
private void doKeyDownloadForUsers(final List<String> downloadUsers, final ApiCallback<MXUsersDevicesMap<MXDeviceInfo>> callback) {
    Log.d(LOG_TAG, "## doKeyDownloadForUsers() : doKeyDownloadForUsers " + downloadUsers);
    // get the user ids which did not already trigger a keys download
    final List<String> filteredUsers = addDownloadKeysPromise(downloadUsers, callback);
    // if there is no new keys request
    if (0 == filteredUsers.size()) {
        // trigger nothing
        return;
    }
    // sanity check
    if ((null == mxSession.getDataHandler()) || (null == mxSession.getDataHandler().getStore())) {
        return;
    }
    mIsDownloadingKeys = true;
    // track the race condition while sending requests
    // we defines a tag for each request
    // and test if the response is the latest request one
    final String downloadToken = filteredUsers.hashCode() + " " + System.currentTimeMillis();
    for (String userId : filteredUsers) {
        mPendingDownloadKeysRequestToken.put(userId, downloadToken);
    }
    mxSession.getCryptoRestClient().downloadKeysForUsers(filteredUsers, mxSession.getDataHandler().getStore().getEventStreamToken(), new ApiCallback<KeysQueryResponse>() {

        @Override
        public void onSuccess(final KeysQueryResponse keysQueryResponse) {
            mxCrypto.getEncryptingThreadHandler().post(new Runnable() {

                @Override
                public void run() {
                    Log.d(LOG_TAG, "## doKeyDownloadForUsers() : Got keys for " + filteredUsers.size() + " users");
                    MXDeviceInfo myDevice = mxCrypto.getMyDevice();
                    IMXCryptoStore cryptoStore = mxCrypto.getCryptoStore();
                    List<String> userIdsList = new ArrayList<>(filteredUsers);
                    for (String userId : userIdsList) {
                        // test if the response is the latest request one
                        if (!TextUtils.equals(mPendingDownloadKeysRequestToken.get(userId), downloadToken)) {
                            Log.e(LOG_TAG, "## doKeyDownloadForUsers() : Another update in the queue for " + userId + " not marking up-to-date");
                            filteredUsers.remove(userId);
                        } else {
                            Map<String, MXDeviceInfo> devices = keysQueryResponse.deviceKeys.get(userId);
                            Log.d(LOG_TAG, "## doKeyDownloadForUsers() : Got keys for " + userId + " : " + devices);
                            if (null != devices) {
                                HashMap<String, MXDeviceInfo> mutableDevices = new HashMap<>(devices);
                                ArrayList<String> deviceIds = new ArrayList<>(mutableDevices.keySet());
                                for (String deviceId : deviceIds) {
                                    // the user has been logged out
                                    if (null == cryptoStore) {
                                        break;
                                    }
                                    // Get the potential previously store device keys for this device
                                    MXDeviceInfo previouslyStoredDeviceKeys = cryptoStore.getUserDevice(deviceId, userId);
                                    MXDeviceInfo deviceInfo = mutableDevices.get(deviceId);
                                    // the self device must be seen as verified
                                    if (TextUtils.equals(deviceInfo.deviceId, myDevice.deviceId) && TextUtils.equals(userId, myDevice.userId)) {
                                        deviceInfo.mVerified = MXDeviceInfo.DEVICE_VERIFICATION_VERIFIED;
                                    }
                                    // Validate received keys
                                    if (!validateDeviceKeys(deviceInfo, userId, deviceId, previouslyStoredDeviceKeys)) {
                                        // New device keys are not valid. Do not store them
                                        mutableDevices.remove(deviceId);
                                        if (null != previouslyStoredDeviceKeys) {
                                            // But keep old validated ones if any
                                            mutableDevices.put(deviceId, previouslyStoredDeviceKeys);
                                        }
                                    } else if (null != previouslyStoredDeviceKeys) {
                                        // The verified status is not sync'ed with hs.
                                        // This is a client side information, valid only for this client.
                                        // So, transfer its previous value
                                        mutableDevices.get(deviceId).mVerified = previouslyStoredDeviceKeys.mVerified;
                                    }
                                }
                                // Update the store
                                // Note that devices which aren't in the response will be removed from the stores
                                cryptoStore.storeUserDevices(userId, mutableDevices);
                            }
                            // the response is the latest request one
                            mPendingDownloadKeysRequestToken.remove(userId);
                        }
                    }
                    onKeysDownloadSucceed(filteredUsers, keysQueryResponse.failures);
                }
            });
        }

        private void onFailed() {
            mxCrypto.getEncryptingThreadHandler().post(new Runnable() {

                @Override
                public void run() {
                    List<String> userIdsList = new ArrayList<>(filteredUsers);
                    // test if the response is the latest request one
                    for (String userId : userIdsList) {
                        if (!TextUtils.equals(mPendingDownloadKeysRequestToken.get(userId), downloadToken)) {
                            Log.e(LOG_TAG, "## doKeyDownloadForUsers() : Another update in the queue for " + userId + " not marking up-to-date");
                            filteredUsers.remove(userId);
                        } else {
                            // the response is the latest request one
                            mPendingDownloadKeysRequestToken.remove(userId);
                        }
                    }
                    onKeysDownloadFailed(filteredUsers);
                }
            });
        }

        @Override
        public void onNetworkError(Exception e) {
            Log.e(LOG_TAG, "##doKeyDownloadForUsers() : onNetworkError " + e.getMessage());
            onFailed();
            if (null != callback) {
                callback.onNetworkError(e);
            }
        }

        @Override
        public void onMatrixError(MatrixError e) {
            Log.e(LOG_TAG, "##doKeyDownloadForUsers() : onMatrixError " + e.getMessage());
            onFailed();
            if (null != callback) {
                callback.onMatrixError(e);
            }
        }

        @Override
        public void onUnexpectedError(Exception e) {
            Log.e(LOG_TAG, "##doKeyDownloadForUsers() : onUnexpectedError " + e.getMessage());
            onFailed();
            if (null != callback) {
                callback.onUnexpectedError(e);
            }
        }
    });
}
Also used : IMXCryptoStore(org.matrix.androidsdk.data.cryptostore.IMXCryptoStore) HashMap(java.util.HashMap) MXDeviceInfo(org.matrix.androidsdk.crypto.data.MXDeviceInfo) ArrayList(java.util.ArrayList) KeysQueryResponse(org.matrix.androidsdk.rest.model.crypto.KeysQueryResponse) MatrixError(org.matrix.androidsdk.rest.model.MatrixError)

Example 20 with MatrixError

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

the class MXCallsManager method refreshTurnServer.

/**
 * Refresh the turn servers.
 */
private void refreshTurnServer() {
    if (mSuspendTurnServerRefresh) {
        return;
    }
    Log.d(LOG_TAG, "## refreshTurnServer () starts");
    mUIThreadHandler.post(new Runnable() {

        @Override
        public void run() {
            mCallResClient.getTurnServer(new ApiCallback<JsonObject>() {

                private void restartAfter(int msDelay) {
                    // "ttl" seems invalid
                    if (msDelay <= 0) {
                        Log.e(LOG_TAG, "## refreshTurnServer() : invalid delay " + msDelay);
                    } else {
                        if (null != mTurnServerTimer) {
                            mTurnServerTimer.cancel();
                        }
                        try {
                            mTurnServerTimer = new Timer();
                            mTurnServerTimer.schedule(new TimerTask() {

                                @Override
                                public void run() {
                                    if (mTurnServerTimer != null) {
                                        mTurnServerTimer.cancel();
                                        mTurnServerTimer = null;
                                    }
                                    refreshTurnServer();
                                }
                            }, msDelay);
                        } catch (Throwable e) {
                            Log.e(LOG_TAG, "## refreshTurnServer() failed to start the timer");
                            if (null != mTurnServerTimer) {
                                mTurnServerTimer.cancel();
                                mTurnServerTimer = null;
                            }
                            refreshTurnServer();
                        }
                    }
                }

                @Override
                public void onSuccess(JsonObject info) {
                    // privacy
                    Log.d(LOG_TAG, "## refreshTurnServer () : onSuccess");
                    if (null != info) {
                        if (info.has("uris")) {
                            synchronized (LOG_TAG) {
                                mTurnServer = info;
                            }
                        }
                        if (info.has("ttl")) {
                            int ttl = 60000;
                            try {
                                ttl = info.get("ttl").getAsInt();
                                // restart a 90 % before ttl expires
                                ttl = ttl * 9 / 10;
                            } catch (Exception e) {
                                Log.e(LOG_TAG, "Fail to retrieve ttl " + e.getMessage());
                            }
                            Log.d(LOG_TAG, "## refreshTurnServer () : onSuccess : retry after " + ttl + " seconds");
                            restartAfter(ttl * 1000);
                        }
                    }
                }

                @Override
                public void onNetworkError(Exception e) {
                    Log.e(LOG_TAG, "## refreshTurnServer () : onNetworkError " + e);
                    restartAfter(60000);
                }

                @Override
                public void onMatrixError(MatrixError e) {
                    Log.e(LOG_TAG, "## refreshTurnServer () : onMatrixError() : " + e.errcode);
                    if (TextUtils.equals(e.errcode, MatrixError.LIMIT_EXCEEDED) && (null != e.retry_after_ms)) {
                        Log.e(LOG_TAG, "## refreshTurnServer () : onMatrixError() : retry after " + e.retry_after_ms + " ms");
                        restartAfter(e.retry_after_ms);
                    }
                }

                @Override
                public void onUnexpectedError(Exception e) {
                // should never happen
                }
            });
        }
    });
}
Also used : Timer(java.util.Timer) TimerTask(java.util.TimerTask) SimpleApiCallback(org.matrix.androidsdk.rest.callback.SimpleApiCallback) ApiCallback(org.matrix.androidsdk.rest.callback.ApiCallback) JsonObject(com.google.gson.JsonObject) MatrixError(org.matrix.androidsdk.rest.model.MatrixError)

Aggregations

MatrixError (org.matrix.androidsdk.rest.model.MatrixError)73 HashMap (java.util.HashMap)41 CountDownLatch (java.util.concurrent.CountDownLatch)39 Room (org.matrix.androidsdk.data.Room)33 JsonObject (com.google.gson.JsonObject)31 Test (org.junit.Test)30 Event (org.matrix.androidsdk.rest.model.Event)27 MXEventListener (org.matrix.androidsdk.listeners.MXEventListener)25 ArrayList (java.util.ArrayList)24 Context (android.content.Context)23 RoomState (org.matrix.androidsdk.data.RoomState)20 MXDeviceInfo (org.matrix.androidsdk.crypto.data.MXDeviceInfo)17 ApiCallback (org.matrix.androidsdk.rest.callback.ApiCallback)15 MXUsersDevicesMap (org.matrix.androidsdk.crypto.data.MXUsersDevicesMap)13 IMXStore (org.matrix.androidsdk.data.store.IMXStore)12 Credentials (org.matrix.androidsdk.rest.model.login.Credentials)12 Uri (android.net.Uri)10 MXFileStore (org.matrix.androidsdk.data.store.MXFileStore)10 EventTimeline (org.matrix.androidsdk.data.EventTimeline)9 SimpleApiCallback (org.matrix.androidsdk.rest.callback.SimpleApiCallback)7