Search in sources :

Example 11 with ApiCallback

use of org.matrix.androidsdk.rest.callback.ApiCallback in project matrix-android-sdk by matrix-org.

the class MXMegolmDecryption method shareKeysWithDevice.

@Override
public void shareKeysWithDevice(final IncomingRoomKeyRequest request) {
    // sanity checks
    if ((null == request) || (null == request.mRequestBody)) {
        return;
    }
    final String userId = request.mUserId;
    mSession.getCrypto().getDeviceList().downloadKeys(Arrays.asList(userId), false, new ApiCallback<MXUsersDevicesMap<MXDeviceInfo>>() {

        @Override
        public void onSuccess(MXUsersDevicesMap<MXDeviceInfo> devicesMap) {
            final String deviceId = request.mDeviceId;
            final MXDeviceInfo deviceInfo = mSession.getCrypto().mCryptoStore.getUserDevice(deviceId, userId);
            if (null != deviceInfo) {
                final RoomKeyRequestBody body = request.mRequestBody;
                HashMap<String, ArrayList<MXDeviceInfo>> devicesByUser = new HashMap<>();
                devicesByUser.put(userId, new ArrayList<>(Arrays.asList(deviceInfo)));
                mSession.getCrypto().ensureOlmSessionsForDevices(devicesByUser, new ApiCallback<MXUsersDevicesMap<MXOlmSessionResult>>() {

                    @Override
                    public void onSuccess(MXUsersDevicesMap<MXOlmSessionResult> map) {
                        MXOlmSessionResult olmSessionResult = map.getObject(deviceId, userId);
                        if ((null == olmSessionResult) || (null == olmSessionResult.mSessionId)) {
                            // so just skip it.
                            return;
                        }
                        Log.d(LOG_TAG, "## shareKeysWithDevice() : sharing keys for session " + body.sender_key + "|" + body.session_id + " with device " + userId + ":" + deviceId);
                        MXOlmInboundGroupSession2 inboundGroupSession = mSession.getCrypto().getOlmDevice().getInboundGroupSession(body.session_id, body.sender_key, body.room_id);
                        Map<String, Object> payloadJson = new HashMap<>();
                        payloadJson.put("type", Event.EVENT_TYPE_FORWARDED_ROOM_KEY);
                        payloadJson.put("content", inboundGroupSession.exportKeys());
                        Map<String, Object> encodedPayload = mSession.getCrypto().encryptMessage(payloadJson, Arrays.asList(deviceInfo));
                        MXUsersDevicesMap<Map<String, Object>> sendToDeviceMap = new MXUsersDevicesMap<>();
                        sendToDeviceMap.setObject(encodedPayload, userId, deviceId);
                        Log.d(LOG_TAG, "## shareKeysWithDevice() : sending to " + userId + ":" + deviceId);
                        mSession.getCryptoRestClient().sendToDevice(Event.EVENT_TYPE_MESSAGE_ENCRYPTED, sendToDeviceMap, new ApiCallback<Void>() {

                            @Override
                            public void onSuccess(Void info) {
                                Log.d(LOG_TAG, "## shareKeysWithDevice() : sent to " + userId + ":" + deviceId);
                            }

                            @Override
                            public void onNetworkError(Exception e) {
                                Log.e(LOG_TAG, "## shareKeysWithDevice() : sendToDevice " + userId + ":" + deviceId + " failed " + e.getMessage());
                            }

                            @Override
                            public void onMatrixError(MatrixError e) {
                                Log.e(LOG_TAG, "## shareKeysWithDevice() : sendToDevice " + userId + ":" + deviceId + " failed " + e.getMessage());
                            }

                            @Override
                            public void onUnexpectedError(Exception e) {
                                Log.e(LOG_TAG, "## shareKeysWithDevice() : sendToDevice " + userId + ":" + deviceId + " failed " + e.getMessage());
                            }
                        });
                    }

                    @Override
                    public void onNetworkError(Exception e) {
                        Log.e(LOG_TAG, "## shareKeysWithDevice() : ensureOlmSessionsForDevices " + userId + ":" + deviceId + " failed " + e.getMessage());
                    }

                    @Override
                    public void onMatrixError(MatrixError e) {
                        Log.e(LOG_TAG, "## shareKeysWithDevice() : ensureOlmSessionsForDevices " + userId + ":" + deviceId + " failed " + e.getMessage());
                    }

                    @Override
                    public void onUnexpectedError(Exception e) {
                        Log.e(LOG_TAG, "## shareKeysWithDevice() : ensureOlmSessionsForDevices " + userId + ":" + deviceId + " failed " + e.getMessage());
                    }
                });
            } else {
                Log.e(LOG_TAG, "## shareKeysWithDevice() : ensureOlmSessionsForDevices " + userId + ":" + deviceId + " not found");
            }
        }

        @Override
        public void onNetworkError(Exception e) {
            Log.e(LOG_TAG, "## shareKeysWithDevice() : downloadKeys " + userId + " failed " + e.getMessage());
        }

        @Override
        public void onMatrixError(MatrixError e) {
            Log.e(LOG_TAG, "## shareKeysWithDevice() : downloadKeys " + userId + " failed " + e.getMessage());
        }

        @Override
        public void onUnexpectedError(Exception e) {
            Log.e(LOG_TAG, "## shareKeysWithDevice() : downloadKeys " + userId + " failed " + e.getMessage());
        }
    });
}
Also used : HashMap(java.util.HashMap) ApiCallback(org.matrix.androidsdk.rest.callback.ApiCallback) MXOlmSessionResult(org.matrix.androidsdk.crypto.data.MXOlmSessionResult) MXDeviceInfo(org.matrix.androidsdk.crypto.data.MXDeviceInfo) ArrayList(java.util.ArrayList) MXUsersDevicesMap(org.matrix.androidsdk.crypto.data.MXUsersDevicesMap) MXDecryptionException(org.matrix.androidsdk.crypto.MXDecryptionException) RoomKeyRequestBody(org.matrix.androidsdk.rest.model.crypto.RoomKeyRequestBody) MXOlmInboundGroupSession2(org.matrix.androidsdk.crypto.data.MXOlmInboundGroupSession2) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) HashMap(java.util.HashMap) MXUsersDevicesMap(org.matrix.androidsdk.crypto.data.MXUsersDevicesMap) Map(java.util.Map)

Example 12 with ApiCallback

use of org.matrix.androidsdk.rest.callback.ApiCallback in project matrix-android-sdk by matrix-org.

the class MXMegolmEncryption method encryptEventContent.

@Override
public void encryptEventContent(final JsonElement eventContent, final String eventType, final List<String> userIds, final ApiCallback<JsonElement> callback) {
    // Queue the encryption request
    // It will be processed when everything is set up
    MXQueuedEncryption queuedEncryption = new MXQueuedEncryption();
    queuedEncryption.mEventContent = eventContent;
    queuedEncryption.mEventType = eventType;
    queuedEncryption.mApiCallback = callback;
    synchronized (mPendingEncryptions) {
        mPendingEncryptions.add(queuedEncryption);
    }
    final long t0 = System.currentTimeMillis();
    Log.d(LOG_TAG, "## encryptEventContent () starts");
    getDevicesInRoom(userIds, new ApiCallback<MXUsersDevicesMap<MXDeviceInfo>>() {

        /**
         * A network error has been received while encrypting
         * @param e the exception
         */
        private void dispatchNetworkError(Exception e) {
            Log.e(LOG_TAG, "## encryptEventContent() : onNetworkError " + e.getMessage());
            List<MXQueuedEncryption> queuedEncryptions = getPendingEncryptions();
            for (MXQueuedEncryption queuedEncryption : queuedEncryptions) {
                queuedEncryption.mApiCallback.onNetworkError(e);
            }
            synchronized (mPendingEncryptions) {
                mPendingEncryptions.removeAll(queuedEncryptions);
            }
        }

        /**
         * A matrix error has been received while encrypting
         * @param e the exception
         */
        private void dispatchMatrixError(MatrixError e) {
            Log.e(LOG_TAG, "## encryptEventContent() : onMatrixError " + e.getMessage());
            List<MXQueuedEncryption> queuedEncryptions = getPendingEncryptions();
            for (MXQueuedEncryption queuedEncryption : queuedEncryptions) {
                queuedEncryption.mApiCallback.onMatrixError(e);
            }
            synchronized (mPendingEncryptions) {
                mPendingEncryptions.removeAll(queuedEncryptions);
            }
        }

        /**
         * An unexpected error has been received while encrypting
         * @param e the exception
         */
        private void dispatchUnexpectedError(Exception e) {
            Log.e(LOG_TAG, "## onUnexpectedError() : onMatrixError " + e.getMessage());
            List<MXQueuedEncryption> queuedEncryptions = getPendingEncryptions();
            for (MXQueuedEncryption queuedEncryption : queuedEncryptions) {
                queuedEncryption.mApiCallback.onUnexpectedError(e);
            }
            synchronized (mPendingEncryptions) {
                mPendingEncryptions.removeAll(queuedEncryptions);
            }
        }

        @Override
        public void onSuccess(MXUsersDevicesMap<MXDeviceInfo> devicesInRoom) {
            ensureOutboundSession(devicesInRoom, new ApiCallback<MXOutboundSessionInfo>() {

                @Override
                public void onSuccess(final MXOutboundSessionInfo session) {
                    mCrypto.getEncryptingThreadHandler().post(new Runnable() {

                        @Override
                        public void run() {
                            Log.d(LOG_TAG, "## encryptEventContent () processPendingEncryptions after " + (System.currentTimeMillis() - t0) + "ms");
                            processPendingEncryptions(session);
                        }
                    });
                }

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

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

                @Override
                public void onUnexpectedError(Exception e) {
                    dispatchUnexpectedError(e);
                }
            });
        }

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

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

        @Override
        public void onUnexpectedError(Exception e) {
            dispatchUnexpectedError(e);
        }
    });
}
Also used : ApiCallback(org.matrix.androidsdk.rest.callback.ApiCallback) MXDeviceInfo(org.matrix.androidsdk.crypto.data.MXDeviceInfo) MXQueuedEncryption(org.matrix.androidsdk.crypto.data.MXQueuedEncryption) MXUsersDevicesMap(org.matrix.androidsdk.crypto.data.MXUsersDevicesMap) ArrayList(java.util.ArrayList) List(java.util.List) MatrixError(org.matrix.androidsdk.rest.model.MatrixError)

Example 13 with ApiCallback

use of org.matrix.androidsdk.rest.callback.ApiCallback in project matrix-android-sdk by matrix-org.

the class MatrixMessageListFragment method add.

/**
 * Add a media item in the room.
 */
private void add(final RoomMediaMessage roomMediaMessage) {
    MessageRow messageRow = addMessageRow(roomMediaMessage);
    // add sanity check
    if (null == messageRow) {
        return;
    }
    final Event event = messageRow.getEvent();
    if (!event.isUndeliverable()) {
        ApiCallback<Void> callback = new ApiCallback<Void>() {

            @Override
            public void onSuccess(Void info) {
                getUiHandler().post(new Runnable() {

                    @Override
                    public void run() {
                        onMessageSendingSucceeded(event);
                    }
                });
            }

            private void commonFailure(final Event event) {
                getUiHandler().post(new Runnable() {

                    @Override
                    public void run() {
                        Activity activity = getActivity();
                        if (null != activity) {
                            // display the error message only if the message cannot be resent
                            if ((null != event.unsentException) && (event.isUndeliverable())) {
                                if ((event.unsentException instanceof RetrofitError) && ((RetrofitError) event.unsentException).isNetworkError()) {
                                    Toast.makeText(activity, activity.getString(R.string.unable_to_send_message) + " : " + getActivity().getString(R.string.network_error), Toast.LENGTH_LONG).show();
                                } else {
                                    Toast.makeText(activity, activity.getString(R.string.unable_to_send_message) + " : " + event.unsentException.getLocalizedMessage(), Toast.LENGTH_LONG).show();
                                }
                            } else if (null != event.unsentMatrixError) {
                                String localised = (event.unsentMatrixError instanceof MXCryptoError) ? ((MXCryptoError) event.unsentMatrixError).getDetailedErrorDescription() : event.unsentMatrixError.getLocalizedMessage();
                                Toast.makeText(activity, activity.getString(R.string.unable_to_send_message) + " : " + localised, Toast.LENGTH_LONG).show();
                            }
                            mAdapter.notifyDataSetChanged();
                            onMessageSendingFailed(event);
                        }
                    }
                });
            }

            @Override
            public void onNetworkError(final Exception e) {
                commonFailure(event);
            }

            @Override
            public void onMatrixError(final MatrixError e) {
                // do not display toast if the sending failed because of unknown deviced (e2e issue)
                if (event.mSentState == Event.SentState.FAILED_UNKNOWN_DEVICES) {
                    getUiHandler().post(new Runnable() {

                        @Override
                        public void run() {
                            mAdapter.notifyDataSetChanged();
                            onUnknownDevices(event, (MXCryptoError) e);
                        }
                    });
                } else {
                    commonFailure(event);
                }
            }

            @Override
            public void onUnexpectedError(final Exception e) {
                commonFailure(event);
            }
        };
        roomMediaMessage.setEventSendingCallback(callback);
    }
}
Also used : ApiCallback(org.matrix.androidsdk.rest.callback.ApiCallback) SimpleApiCallback(org.matrix.androidsdk.rest.callback.SimpleApiCallback) Activity(android.app.Activity) MessageRow(org.matrix.androidsdk.adapters.MessageRow) MotionEvent(android.view.MotionEvent) Event(org.matrix.androidsdk.rest.model.Event) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) RetrofitError(retrofit.RetrofitError) MXCryptoError(org.matrix.androidsdk.crypto.MXCryptoError)

Example 14 with ApiCallback

use of org.matrix.androidsdk.rest.callback.ApiCallback in project matrix-android-sdk by matrix-org.

the class MatrixMessageListFragment method requestSearchHistory.

/**
 * Search the pattern on a pagination server side.
 */
public void requestSearchHistory() {
    // there is no more server message
    if (TextUtils.isEmpty(mNextBatch)) {
        mIsBackPaginating = false;
        return;
    }
    mIsBackPaginating = true;
    final int firstPos = mMessageListView.getFirstVisiblePosition();
    final String fPattern = mPattern;
    final int countBeforeUpdate = mAdapter.getCount();
    showLoadingBackProgress();
    List<String> roomIds = null;
    if (null != mRoom) {
        roomIds = Arrays.asList(mRoom.getRoomId());
    }
    ApiCallback<SearchResponse> callback = new ApiCallback<SearchResponse>() {

        @Override
        public void onSuccess(final SearchResponse searchResponse) {
            // check that the pattern was not modified before the end of the search
            if (TextUtils.equals(mPattern, fPattern)) {
                List<SearchResult> searchResults = searchResponse.searchCategories.roomEvents.results;
                // is there any result to display
                if (0 != searchResults.size()) {
                    mAdapter.setNotifyOnChange(false);
                    for (SearchResult searchResult : searchResults) {
                        MessageRow row = new MessageRow(searchResult.result, (null == mRoom) ? null : mRoom.getState());
                        mAdapter.insert(row, 0);
                    }
                    mNextBatch = searchResponse.searchCategories.roomEvents.nextBatch;
                    // Scroll the list down to where it was before adding rows to the top
                    getUiHandler().post(new Runnable() {

                        @Override
                        public void run() {
                            final int expectedFirstPos = firstPos + (mAdapter.getCount() - countBeforeUpdate);
                            // trick to avoid that the list jump to the latest item.
                            mMessageListView.lockSelectionOnResize();
                            mAdapter.notifyDataSetChanged();
                            // do not use count because some messages are not displayed
                            // so we compute the new pos
                            mMessageListView.setSelection(expectedFirstPos);
                            mMessageListView.post(new Runnable() {

                                @Override
                                public void run() {
                                    mIsBackPaginating = false;
                                    // fill the history
                                    if (mMessageListView.getFirstVisiblePosition() <= 2) {
                                        requestSearchHistory();
                                    }
                                }
                            });
                        }
                    });
                } else {
                    mIsBackPaginating = false;
                }
                hideLoadingBackProgress();
            }
        }

        private void onError() {
            mIsBackPaginating = false;
            hideLoadingBackProgress();
        }

        // the request will be auto restarted when a valid network will be found
        @Override
        public void onNetworkError(Exception e) {
            Log.e(LOG_TAG, "Network error: " + e.getMessage());
            onError();
        }

        @Override
        public void onMatrixError(MatrixError e) {
            Log.e(LOG_TAG, "Matrix error" + " : " + e.errcode + " - " + e.getMessage());
            onError();
        }

        @Override
        public void onUnexpectedError(Exception e) {
            Log.e(LOG_TAG, "onUnexpectedError error" + e.getMessage());
            onError();
        }
    };
    if (mIsMediaSearch) {
        mSession.searchMediasByName(mPattern, roomIds, mNextBatch, callback);
    } else {
        mSession.searchMessagesByText(mPattern, roomIds, mNextBatch, callback);
    }
}
Also used : ApiCallback(org.matrix.androidsdk.rest.callback.ApiCallback) SimpleApiCallback(org.matrix.androidsdk.rest.callback.SimpleApiCallback) SearchResult(org.matrix.androidsdk.rest.model.search.SearchResult) SearchResponse(org.matrix.androidsdk.rest.model.search.SearchResponse) MessageRow(org.matrix.androidsdk.adapters.MessageRow) MatrixError(org.matrix.androidsdk.rest.model.MatrixError)

Example 15 with ApiCallback

use of org.matrix.androidsdk.rest.callback.ApiCallback in project matrix-android-sdk by matrix-org.

the class EventsRestClient method searchMediasByText.

/**
 * Search a media from its name.
 *
 * @param name        the text to search for.
 * @param rooms       a list of rooms to search in. nil means all rooms the user is in.
 * @param beforeLimit the number of events to get before the matching results.
 * @param afterLimit  the number of events to get after the matching results.
 * @param nextBatch   the token to pass for doing pagination from a previous response.
 * @param callback    the request callback
 */
public void searchMediasByText(final String name, final List<String> rooms, final int beforeLimit, final int afterLimit, final String nextBatch, final ApiCallback<SearchResponse> callback) {
    SearchParams searchParams = new SearchParams();
    SearchRoomEventCategoryParams searchEventParams = new SearchRoomEventCategoryParams();
    searchEventParams.search_term = name;
    searchEventParams.order_by = "recent";
    searchEventParams.event_context = new HashMap<>();
    searchEventParams.event_context.put("before_limit", beforeLimit);
    searchEventParams.event_context.put("after_limit", afterLimit);
    searchEventParams.event_context.put("include_profile", true);
    searchEventParams.filter = new HashMap<>();
    if (null != rooms) {
        searchEventParams.filter.put("rooms", rooms);
    }
    ArrayList<String> types = new ArrayList<>();
    types.add(Event.EVENT_TYPE_MESSAGE);
    searchEventParams.filter.put("types", types);
    searchEventParams.filter.put("contains_url", true);
    searchParams.search_categories = new HashMap<>();
    searchParams.search_categories.put("room_events", searchEventParams);
    // other unused filter items
    // not_types
    // not_rooms
    // senders
    // not_senders
    final String uid = System.currentTimeMillis() + "";
    mSearchEventsMediaNameIdentifier = uid + name;
    final String description = "searchMediasByText";
    try {
        // don't retry to send the request
        // if the search fails, stop it
        mApi.searchEvents(searchParams, nextBatch, new RestAdapterCallback<SearchResponse>(description, null, new ApiCallback<SearchResponse>() {

            /**
             * Tells if the current response for the latest request.
             *
             * @return true if it is the response of the latest request.
             */
            private boolean isActiveRequest() {
                return TextUtils.equals(mSearchEventsMediaNameIdentifier, uid + name);
            }

            @Override
            public void onSuccess(SearchResponse newSearchResponse) {
                if (isActiveRequest()) {
                    callback.onSuccess(newSearchResponse);
                    mSearchEventsMediaNameIdentifier = null;
                }
            }

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

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

            @Override
            public void onUnexpectedError(Exception e) {
                if (isActiveRequest()) {
                    callback.onUnexpectedError(e);
                    mSearchEventsMediaNameIdentifier = null;
                }
            }
        }, new RestAdapterCallback.RequestRetryCallBack() {

            @Override
            public void onRetry() {
                searchMediasByText(name, rooms, beforeLimit, afterLimit, nextBatch, callback);
            }
        }));
    } catch (Throwable t) {
        callback.onUnexpectedError(new Exception(t));
    }
}
Also used : SearchRoomEventCategoryParams(org.matrix.androidsdk.rest.model.search.SearchRoomEventCategoryParams) SearchParams(org.matrix.androidsdk.rest.model.search.SearchParams) ApiCallback(org.matrix.androidsdk.rest.callback.ApiCallback) ArrayList(java.util.ArrayList) SearchResponse(org.matrix.androidsdk.rest.model.search.SearchResponse) MatrixError(org.matrix.androidsdk.rest.model.MatrixError)

Aggregations

ApiCallback (org.matrix.androidsdk.rest.callback.ApiCallback)15 MatrixError (org.matrix.androidsdk.rest.model.MatrixError)15 ArrayList (java.util.ArrayList)8 SimpleApiCallback (org.matrix.androidsdk.rest.callback.SimpleApiCallback)7 Room (org.matrix.androidsdk.data.Room)6 JsonObject (com.google.gson.JsonObject)3 HashMap (java.util.HashMap)3 MXDeviceInfo (org.matrix.androidsdk.crypto.data.MXDeviceInfo)3 Event (org.matrix.androidsdk.rest.model.Event)3 RoomMember (org.matrix.androidsdk.rest.model.RoomMember)3 SearchResponse (org.matrix.androidsdk.rest.model.search.SearchResponse)3 List (java.util.List)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 MessageRow (org.matrix.androidsdk.adapters.MessageRow)2 MXCryptoError (org.matrix.androidsdk.crypto.MXCryptoError)2 MXDecryptionException (org.matrix.androidsdk.crypto.MXDecryptionException)2 MXUsersDevicesMap (org.matrix.androidsdk.crypto.data.MXUsersDevicesMap)2 RoomState (org.matrix.androidsdk.data.RoomState)2 MXEventListener (org.matrix.androidsdk.listeners.MXEventListener)2 SearchParams (org.matrix.androidsdk.rest.model.search.SearchParams)2