Search in sources :

Example 31 with MatrixError

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

the class UnsentEventsManager method onEventSendingFailed.

/**
 * warns that an event failed to be sent.
 *
 * @param eventDescription             the event description
 * @param ignoreEventTimeLifeInOffline tell if the event timelife is ignored in offline mode
 * @param retrofitError                the retrofit error .
 * @param apiCallback                  the apiCallback.
 * @param requestRetryCallBack         requestRetryCallBack.
 */
public void onEventSendingFailed(final String eventDescription, final boolean ignoreEventTimeLifeInOffline, final RetrofitError retrofitError, final ApiCallback apiCallback, final RestAdapterCallback.RequestRetryCallBack requestRetryCallBack) {
    boolean isManaged = false;
    if (null != eventDescription) {
        Log.d(LOG_TAG, "Fail to send [" + eventDescription + "]");
    }
    if ((null != requestRetryCallBack) && (null != apiCallback)) {
        synchronized (mUnsentEventsMap) {
            UnsentEventSnapshot snapshot;
            // Try to convert this into a Matrix error
            MatrixError mxError = null;
            if (null != retrofitError) {
                try {
                    mxError = (MatrixError) retrofitError.getBodyAs(MatrixError.class);
                } catch (Exception e) {
                    mxError = null;
                }
            }
            // trace the matrix error.
            if ((null != eventDescription) && (null != mxError)) {
                Log.d(LOG_TAG, "Matrix error " + mxError.errcode + " " + mxError.getMessage() + " [" + eventDescription + "]");
                if (MatrixError.isConfigurationErrorCode(mxError.errcode)) {
                    Log.e(LOG_TAG, "## onEventSendingFailed() : invalid token detected");
                    mDataHandler.onConfigurationError(mxError.errcode);
                    triggerErrorCallback(mDataHandler, eventDescription, retrofitError, apiCallback);
                    return;
                }
            }
            int matrixRetryTimeout = -1;
            if ((null != mxError) && MatrixError.LIMIT_EXCEEDED.equals(mxError.errcode) && (null != mxError.retry_after_ms)) {
                matrixRetryTimeout = mxError.retry_after_ms + 200;
            }
            if ((null != retrofitError) && retrofitError.isNetworkError()) {
                UnrecognizedCertificateException unrecCertEx = CertUtil.getCertificateException(retrofitError);
                if (null != unrecCertEx) {
                    Log.e(LOG_TAG, "## onEventSendingFailed() : SSL issue detected");
                    mDataHandler.onSSLCertificateError(unrecCertEx);
                    triggerErrorCallback(mDataHandler, eventDescription, retrofitError, apiCallback);
                    return;
                }
            }
            // some matrix errors are not trapped.
            if ((null == mxError) || !mxError.isSupportedErrorCode() || MatrixError.LIMIT_EXCEEDED.equals(mxError.errcode)) {
                // is it the first time that the event has been sent ?
                if (mUnsentEventsMap.containsKey(apiCallback)) {
                    snapshot = mUnsentEventsMap.get(apiCallback);
                    snapshot.mIsResending = false;
                    snapshot.stopTimer();
                    // assume that LIMIT_EXCEEDED error is not a default retry
                    if (matrixRetryTimeout < 0) {
                        snapshot.mRetryCount++;
                    }
                    // any event has a time life to avoid very old messages
                    long timeLife = 0;
                    // age < 0 means that the event time life is ignored
                    if (snapshot.mAge > 0) {
                        timeLife = System.currentTimeMillis() - snapshot.mAge;
                    }
                    if ((timeLife > MAX_MESSAGE_LIFETIME_MS) || (snapshot.mRetryCount > MAX_RETRIES)) {
                        snapshot.stopTimers();
                        mUnsentEventsMap.remove(apiCallback);
                        mUnsentEvents.remove(snapshot);
                        if (null != eventDescription) {
                            Log.d(LOG_TAG, "Cancel [" + eventDescription + "]");
                        }
                        isManaged = false;
                    } else {
                        isManaged = true;
                    }
                } else {
                    snapshot = new UnsentEventSnapshot();
                    try {
                        snapshot.mAge = ignoreEventTimeLifeInOffline ? -1 : System.currentTimeMillis();
                        snapshot.mRequestRetryCallBack = requestRetryCallBack;
                        snapshot.mRetryCount = 1;
                        snapshot.mEventDescription = eventDescription;
                        mUnsentEventsMap.put(apiCallback, snapshot);
                        mUnsentEvents.add(snapshot);
                        if (mbIsConnected || !ignoreEventTimeLifeInOffline) {
                            // the event has a life time
                            final UnsentEventSnapshot fSnapshot = snapshot;
                            fSnapshot.mLifeTimeTimer = new Timer();
                            fSnapshot.mLifeTimeTimer.schedule(new TimerTask() {

                                @Override
                                public void run() {
                                    try {
                                        if (null != eventDescription) {
                                            Log.d(LOG_TAG, "Cancel to send [" + eventDescription + "]");
                                        }
                                        fSnapshot.stopTimers();
                                        synchronized (mUnsentEventsMap) {
                                            mUnsentEventsMap.remove(apiCallback);
                                            mUnsentEvents.remove(fSnapshot);
                                        }
                                        triggerErrorCallback(mDataHandler, eventDescription, retrofitError, apiCallback);
                                    } catch (Exception e) {
                                        Log.e(LOG_TAG, "## onEventSendingFailed() : failure Msg=" + e.getMessage());
                                    }
                                }
                            }, MAX_MESSAGE_LIFETIME_MS);
                        } else if (ignoreEventTimeLifeInOffline) {
                            Log.d(LOG_TAG, "The request " + eventDescription + " will be sent when a network will be available");
                        }
                    } catch (Throwable throwable) {
                        Log.e(LOG_TAG, "## snapshot creation failed " + throwable.getMessage());
                        if (null != snapshot.mLifeTimeTimer) {
                            snapshot.mLifeTimeTimer.cancel();
                        }
                        mUnsentEventsMap.remove(apiCallback);
                        mUnsentEvents.remove(snapshot);
                        try {
                            triggerErrorCallback(mDataHandler, eventDescription, retrofitError, apiCallback);
                        } catch (Exception e) {
                            Log.e(LOG_TAG, "## onEventSendingFailed() : failure Msg=" + e.getMessage());
                        }
                    }
                    isManaged = true;
                }
                // retry to send the message ?
                if (isManaged) {
                    // 
                    if (mbIsConnected) {
                        int jitterTime = ((int) Math.pow(2, snapshot.mRetryCount)) + (Math.abs(new Random(System.currentTimeMillis()).nextInt()) % RETRY_JITTER_MS);
                        isManaged = snapshot.resendEventAfter((matrixRetryTimeout > 0) ? matrixRetryTimeout : jitterTime);
                    }
                }
            }
        }
    }
    if (!isManaged) {
        Log.d(LOG_TAG, "Cannot resend it");
        triggerErrorCallback(mDataHandler, eventDescription, retrofitError, apiCallback);
    }
}
Also used : Timer(java.util.Timer) TimerTask(java.util.TimerTask) Random(java.util.Random) UnrecognizedCertificateException(org.matrix.androidsdk.ssl.UnrecognizedCertificateException) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) UnrecognizedCertificateException(org.matrix.androidsdk.ssl.UnrecognizedCertificateException)

Example 32 with MatrixError

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

the class MXDataHandler method roomIdByAlias.

/**
 * Retrieve a room Id by its alias.
 *
 * @param roomAlias the room alias
 * @param callback  the asynchronous callback
 */
public void roomIdByAlias(final String roomAlias, final ApiCallback<String> callback) {
    String roomId = null;
    Collection<Room> rooms = getStore().getRooms();
    for (Room room : rooms) {
        if (TextUtils.equals(room.getState().alias, roomAlias)) {
            roomId = room.getRoomId();
            break;
        } else {
            // getAliases cannot be null
            List<String> aliases = room.getState().getAliases();
            for (String alias : aliases) {
                if (TextUtils.equals(alias, roomAlias)) {
                    roomId = room.getRoomId();
                    break;
                }
            }
            // find one matched room id.
            if (null != roomId) {
                break;
            }
        }
    }
    if (null != roomId) {
        final String fRoomId = roomId;
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {

            @Override
            public void run() {
                callback.onSuccess(fRoomId);
            }
        });
    } else {
        mRoomsRestClient.getRoomIdByAlias(roomAlias, new ApiCallback<RoomAliasDescription>() {

            @Override
            public void onSuccess(RoomAliasDescription info) {
                callback.onSuccess(info.room_id);
            }

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

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

            @Override
            public void onUnexpectedError(Exception e) {
                callback.onUnexpectedError(e);
            }
        });
    }
}
Also used : RoomAliasDescription(org.matrix.androidsdk.rest.model.RoomAliasDescription) MXOsHandler(org.matrix.androidsdk.util.MXOsHandler) Handler(android.os.Handler) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) Room(org.matrix.androidsdk.data.Room) MXDecryptionException(org.matrix.androidsdk.crypto.MXDecryptionException) UnrecognizedCertificateException(org.matrix.androidsdk.ssl.UnrecognizedCertificateException)

Example 33 with MatrixError

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

the class MXDataHandler method getDirectChatRoomIdsList.

/**
 * @return the direct chat room ids list
 */
public List<String> getDirectChatRoomIdsList() {
    if (null != mLocalDirectChatRoomIdsList)
        return mLocalDirectChatRoomIdsList;
    IMXStore store = getStore();
    List<String> directChatRoomIdsList = new ArrayList<>();
    if (null == store) {
        Log.e(LOG_TAG, "## getDirectChatRoomIdsList() : null store");
        return directChatRoomIdsList;
    }
    Collection<List<String>> listOfList = null;
    if (null != store.getDirectChatRoomsDict()) {
        listOfList = store.getDirectChatRoomsDict().values();
    }
    // if the direct messages entry has been defined
    if (null != listOfList) {
        for (List<String> list : listOfList) {
            for (String roomId : list) {
                // test if the room is defined once and exists
                if ((directChatRoomIdsList.indexOf(roomId) < 0) && (null != store.getRoom(roomId))) {
                    directChatRoomIdsList.add(roomId);
                }
            }
        }
    } else {
        // background compatibility heuristic (named looksLikeDirectMessageRoom in the JS)
        ArrayList<RoomIdsListRetroCompat> directChatRoomIdsListRetValue = new ArrayList<>();
        getDirectChatRoomIdsListRetroCompat(store, directChatRoomIdsListRetValue);
        // force direct chat room list to be updated with retro compatibility rooms values
        if (0 != directChatRoomIdsListRetValue.size()) {
            forceDirectChatRoomValue(directChatRoomIdsListRetValue, new ApiCallback<Void>() {

                @Override
                public void onSuccess(Void info) {
                    Log.d(LOG_TAG, "## getDirectChatRoomIdsList(): background compatibility heuristic => account_data update succeed");
                }

                @Override
                public void onMatrixError(MatrixError e) {
                    if (MatrixError.FORBIDDEN.equals(e.errcode)) {
                        Log.e(LOG_TAG, "## getDirectChatRoomIdsList(): onMatrixError Msg=" + e.error);
                    }
                }

                @Override
                public void onNetworkError(Exception e) {
                    Log.e(LOG_TAG, "## getDirectChatRoomIdsList(): onNetworkError Msg=" + e.getMessage());
                }

                @Override
                public void onUnexpectedError(Exception e) {
                    Log.e(LOG_TAG, "## getDirectChatRoomIdsList(): onUnexpectedError Msg=" + e.getMessage());
                }
            });
        }
    }
    return mLocalDirectChatRoomIdsList = directChatRoomIdsList;
}
Also used : IMXStore(org.matrix.androidsdk.data.store.IMXStore) ArrayList(java.util.ArrayList) MXDecryptionException(org.matrix.androidsdk.crypto.MXDecryptionException) UnrecognizedCertificateException(org.matrix.androidsdk.ssl.UnrecognizedCertificateException) List(java.util.List) ArrayList(java.util.ArrayList) MatrixError(org.matrix.androidsdk.rest.model.MatrixError)

Example 34 with MatrixError

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

the class MXDataHandler method retrieveLeftRooms.

/**
 * Retrieve the historical rooms
 *
 * @param callback the asynchronous callback.
 */
public void retrieveLeftRooms(ApiCallback<Void> callback) {
    // already loaded
    if (mAreLeftRoomsSynced) {
        if (null != callback) {
            callback.onSuccess(null);
        }
    } else {
        int count;
        synchronized (mLeftRoomsRefreshCallbacks) {
            if (null != callback) {
                mLeftRoomsRefreshCallbacks.add(callback);
            }
            count = mLeftRoomsRefreshCallbacks.size();
        }
        // start the request only for the first listener
        if (1 == count) {
            mIsRetrievingLeftRooms = true;
            Log.d(LOG_TAG, "## refreshHistoricalRoomsList() : requesting");
            mEventsRestClient.syncFromToken(null, 0, 30000, null, LEFT_ROOMS_FILTER, new ApiCallback<SyncResponse>() {

                @Override
                public void onSuccess(final SyncResponse syncResponse) {
                    Runnable r = new Runnable() {

                        @Override
                        public void run() {
                            if (null != syncResponse.rooms.leave) {
                                Set<String> roomIds = syncResponse.rooms.leave.keySet();
                                // Handle first joined rooms
                                for (String roomId : roomIds) {
                                    Room room = getRoom(mLeftRoomsStore, roomId, true);
                                    // sanity check
                                    if (null != room) {
                                        room.setIsLeft(true);
                                        room.handleJoinedRoomSync(syncResponse.rooms.leave.get(roomId), true);
                                        RoomMember selfMember = room.getState().getMember(getUserId());
                                        // keep only the left rooms (i.e not the banned / kicked ones)
                                        if ((null == selfMember) || !TextUtils.equals(selfMember.membership, RoomMember.MEMBERSHIP_LEAVE)) {
                                            mLeftRoomsStore.deleteRoom(roomId);
                                        }
                                    }
                                }
                                Log.d(LOG_TAG, "## refreshHistoricalRoomsList() : " + mLeftRoomsStore.getRooms().size() + " left rooms");
                            }
                            mIsRetrievingLeftRooms = false;
                            mAreLeftRoomsSynced = true;
                            synchronized (mLeftRoomsRefreshCallbacks) {
                                for (ApiCallback<Void> c : mLeftRoomsRefreshCallbacks) {
                                    c.onSuccess(null);
                                }
                                mLeftRoomsRefreshCallbacks.clear();
                            }
                        }
                    };
                    Thread t = new Thread(r);
                    t.setPriority(Thread.MIN_PRIORITY);
                    t.start();
                }

                @Override
                public void onNetworkError(Exception e) {
                    synchronized (mLeftRoomsRefreshCallbacks) {
                        Log.d(LOG_TAG, "## refreshHistoricalRoomsList() : failed " + e.getMessage());
                        for (ApiCallback<Void> c : mLeftRoomsRefreshCallbacks) {
                            c.onNetworkError(e);
                        }
                        mLeftRoomsRefreshCallbacks.clear();
                    }
                }

                @Override
                public void onMatrixError(MatrixError e) {
                    synchronized (mLeftRoomsRefreshCallbacks) {
                        Log.d(LOG_TAG, "## refreshHistoricalRoomsList() : failed " + e.getMessage());
                        for (ApiCallback<Void> c : mLeftRoomsRefreshCallbacks) {
                            c.onMatrixError(e);
                        }
                        mLeftRoomsRefreshCallbacks.clear();
                    }
                }

                @Override
                public void onUnexpectedError(Exception e) {
                    synchronized (mLeftRoomsRefreshCallbacks) {
                        Log.d(LOG_TAG, "## refreshHistoricalRoomsList() : failed " + e.getMessage());
                        for (ApiCallback<Void> c : mLeftRoomsRefreshCallbacks) {
                            c.onUnexpectedError(e);
                        }
                        mLeftRoomsRefreshCallbacks.clear();
                    }
                }
            });
        }
    }
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) BingRuleSet(org.matrix.androidsdk.rest.model.bingrules.BingRuleSet) ApiCallback(org.matrix.androidsdk.rest.callback.ApiCallback) SimpleApiCallback(org.matrix.androidsdk.rest.callback.SimpleApiCallback) MXDecryptionException(org.matrix.androidsdk.crypto.MXDecryptionException) UnrecognizedCertificateException(org.matrix.androidsdk.ssl.UnrecognizedCertificateException) HandlerThread(android.os.HandlerThread) SyncResponse(org.matrix.androidsdk.rest.model.sync.SyncResponse) RoomMember(org.matrix.androidsdk.rest.model.RoomMember) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) Room(org.matrix.androidsdk.data.Room)

Example 35 with MatrixError

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

the class MXSession method enableCrypto.

/**
 * Enable / disable the crypto.
 *
 * @param cryptoEnabled true to enable the crypto
 * @param callback      the asynchronous callback called when the action has been done
 */
public void enableCrypto(boolean cryptoEnabled, final ApiCallback<Void> callback) {
    if (cryptoEnabled != isCryptoEnabled()) {
        if (cryptoEnabled) {
            Log.d(LOG_TAG, "Crypto is enabled");
            MXFileCryptoStore fileCryptoStore = new MXFileCryptoStore();
            fileCryptoStore.initWithCredentials(mAppContent, mCredentials);
            fileCryptoStore.open();
            mCrypto = new MXCrypto(this, fileCryptoStore);
            mCrypto.start(true, new ApiCallback<Void>() {

                @Override
                public void onSuccess(Void info) {
                    decryptRoomSummaries();
                    if (null != callback) {
                        callback.onSuccess(null);
                    }
                }

                @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 if (null != mCrypto) {
            Log.d(LOG_TAG, "Crypto is disabled");
            IMXCryptoStore store = mCrypto.mCryptoStore;
            mCrypto.close();
            store.deleteStore();
            mCrypto = null;
            mDataHandler.setCrypto(null);
            decryptRoomSummaries();
            if (null != callback) {
                callback.onSuccess(null);
            }
        }
        mDataHandler.setCrypto(mCrypto);
    } else {
        if (null != callback) {
            callback.onSuccess(null);
        }
    }
}
Also used : IMXCryptoStore(org.matrix.androidsdk.data.cryptostore.IMXCryptoStore) MXFileCryptoStore(org.matrix.androidsdk.data.cryptostore.MXFileCryptoStore) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) MXCrypto(org.matrix.androidsdk.crypto.MXCrypto)

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