Search in sources :

Example 21 with MatrixError

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

the class MXMediaDownloadWorkerTask method doInBackground.

// Decode image in background.
@Override
protected Void doInBackground(Integer... params) {
    MatrixError defaultError = new MatrixError();
    defaultError.errcode = MatrixError.UNKNOWN;
    try {
        URL url = new URL(mUrl);
        Log.d(LOG_TAG, "MXMediaDownloadWorkerTask " + this + " starts");
        mDownloadStats = new IMXMediaDownloadListener.DownloadStats();
        // don't known yet
        mDownloadStats.mEstimatedRemainingTime = -1;
        InputStream stream = null;
        int filelen = -1;
        URLConnection connection = null;
        try {
            connection = url.openConnection();
            if (mHsConfig != null && connection instanceof HttpsURLConnection) {
                // Add SSL Socket factory.
                HttpsURLConnection sslConn = (HttpsURLConnection) connection;
                try {
                    sslConn.setSSLSocketFactory(CertUtil.newPinnedSSLSocketFactory(mHsConfig));
                    sslConn.setHostnameVerifier(CertUtil.newHostnameVerifier(mHsConfig));
                } catch (Exception e) {
                    Log.e(LOG_TAG, "doInBackground SSL exception " + e.getMessage());
                }
            }
            // add a timeout to avoid infinite loading display.
            float scale = (null != mNetworkConnectivityReceiver) ? mNetworkConnectivityReceiver.getTimeoutScale() : 1.0f;
            connection.setReadTimeout((int) (DOWNLOAD_TIME_OUT * scale));
            filelen = connection.getContentLength();
            stream = connection.getInputStream();
        } catch (Exception e) {
            Log.e(LOG_TAG, "bitmapForURL : fail to open the connection " + e.getMessage());
            defaultError.error = e.getLocalizedMessage();
            InputStream errorStream = ((HttpsURLConnection) connection).getErrorStream();
            if (null != errorStream) {
                try {
                    BufferedReader streamReader = new BufferedReader(new InputStreamReader(errorStream, "UTF-8"));
                    StringBuilder responseStrBuilder = new StringBuilder();
                    String inputStr;
                    while ((inputStr = streamReader.readLine()) != null) {
                        responseStrBuilder.append(inputStr);
                    }
                    mErrorAsJsonElement = new JsonParser().parse(responseStrBuilder.toString());
                } catch (Exception ee) {
                    Log.e(LOG_TAG, "bitmapForURL : Error parsing error " + ee.getMessage());
                }
            }
            // privacy
            // Log.d(LOG_TAG, "MediaWorkerTask " + mUrl + " does not exist");
            Log.d(LOG_TAG, "MediaWorkerTask an url does not exist");
            // do not try to reload them until the next application launch.
            synchronized (mUnreachableUrls) {
                mUnreachableUrls.add(mUrl);
            }
        }
        dispatchDownloadStart();
        // failed to open the remote stream without having exception
        if ((null == stream) && (null == mErrorAsJsonElement)) {
            mErrorAsJsonElement = new JsonParser().parse("Cannot open " + mUrl);
            // do not try to reload them until the next application launch.
            synchronized (mUnreachableUrls) {
                mUnreachableUrls.add(mUrl);
            }
        }
        // test if the download has not been cancelled
        if (!isDownloadCancelled() && (null == mErrorAsJsonElement)) {
            final long startDownloadTime = System.currentTimeMillis();
            String filename = MXMediaDownloadWorkerTask.buildFileName(mUrl, mMimeType) + ".tmp";
            FileOutputStream fos = new FileOutputStream(new File(mDirectoryFile, filename));
            mDownloadStats.mDownloadId = mUrl;
            mDownloadStats.mProgress = 0;
            mDownloadStats.mDownloadedSize = 0;
            mDownloadStats.mFileSize = filelen;
            mDownloadStats.mElapsedTime = 0;
            mDownloadStats.mEstimatedRemainingTime = -1;
            mDownloadStats.mBitRate = 0;
            final android.os.Handler uiHandler = new android.os.Handler(Looper.getMainLooper());
            final Timer refreshTimer = new Timer();
            uiHandler.post(new Runnable() {

                @Override
                public void run() {
                    try {
                        refreshTimer.scheduleAtFixedRate(new TimerTask() {

                            @Override
                            public void run() {
                                uiHandler.post(new Runnable() {

                                    @Override
                                    public void run() {
                                        if (!mIsDone) {
                                            publishProgress(startDownloadTime);
                                        }
                                    }
                                });
                            }
                        }, new java.util.Date(), 100);
                    } catch (Throwable throwable) {
                        Log.e(LOG_TAG, "scheduleAtFixedRate failed " + throwable.getMessage());
                    }
                }
            });
            try {
                byte[] buf = new byte[DOWNLOAD_BUFFER_READ_SIZE];
                int len;
                while (!isDownloadCancelled() && (len = stream.read(buf)) != -1) {
                    fos.write(buf, 0, len);
                    mDownloadStats.mDownloadedSize += len;
                }
                if (!isDownloadCancelled()) {
                    mDownloadStats.mProgress = 100;
                }
            } catch (OutOfMemoryError outOfMemoryError) {
                Log.e(LOG_TAG, "doInBackground: out of memory");
                defaultError.error = outOfMemoryError.getLocalizedMessage();
            } catch (Exception e) {
                Log.e(LOG_TAG, "doInBackground fail to read image " + e.getMessage());
                defaultError.error = e.getLocalizedMessage();
            }
            mIsDone = true;
            close(stream);
            fos.flush();
            fos.close();
            uiHandler.post(new Runnable() {

                @Override
                public void run() {
                    refreshTimer.cancel();
                }
            });
            if ((null != connection) && (connection instanceof HttpsURLConnection)) {
                ((HttpsURLConnection) connection).disconnect();
            }
            // the file has been successfully downloaded
            if (mDownloadStats.mProgress == 100) {
                try {
                    File originalFile = new File(mDirectoryFile, filename);
                    String newFileName = MXMediaDownloadWorkerTask.buildFileName(mUrl, mMimeType);
                    File newFile = new File(mDirectoryFile, newFileName);
                    if (newFile.exists()) {
                        // Or you could throw here.
                        mApplicationContext.deleteFile(newFileName);
                    }
                    originalFile.renameTo(newFile);
                } catch (Exception e) {
                    Log.e(LOG_TAG, "doInBackground : renaming error " + e.getMessage());
                    defaultError.error = e.getLocalizedMessage();
                }
            }
        }
        if (mDownloadStats.mProgress == 100) {
            Log.d(LOG_TAG, "The download " + this + " is done.");
        } else {
            if (null != mErrorAsJsonElement) {
                Log.d(LOG_TAG, "The download " + this + " failed : mErrorAsJsonElement " + mErrorAsJsonElement.toString());
            } else {
                Log.d(LOG_TAG, "The download " + this + " failed.");
            }
        }
    } catch (Exception e) {
        Log.e(LOG_TAG, "Unable to download media " + this);
        defaultError.error = e.getMessage();
    }
    // build a JSON from the error
    if (!TextUtils.isEmpty(defaultError.error)) {
        mErrorAsJsonElement = JsonUtils.getGson(false).toJsonTree(defaultError);
    }
    // remove the image from the loading one
    synchronized (mPendingDownloadByUrl) {
        mPendingDownloadByUrl.remove(mUrl);
    }
    return null;
}
Also used : URL(java.net.URL) TimerTask(java.util.TimerTask) Handler(android.os.Handler) JsonParser(com.google.gson.JsonParser) InputStreamReader(java.io.InputStreamReader) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) MXOsHandler(org.matrix.androidsdk.util.MXOsHandler) Handler(android.os.Handler) URLConnection(java.net.URLConnection) HttpsURLConnection(javax.net.ssl.HttpsURLConnection) FileNotFoundException(java.io.FileNotFoundException) Timer(java.util.Timer) IMXMediaDownloadListener(org.matrix.androidsdk.listeners.IMXMediaDownloadListener) FileOutputStream(java.io.FileOutputStream) BufferedReader(java.io.BufferedReader) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) File(java.io.File) HttpsURLConnection(javax.net.ssl.HttpsURLConnection)

Example 22 with MatrixError

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

the class MatrixMessageListFragment method redactEvent.

/**
 * Redact an event from its event id.
 *
 * @param eventId the event id.
 */
protected void redactEvent(final String eventId) {
    // Do nothing on success, the event will be hidden when the redaction event comes down the event stream
    mMatrixMessagesFragment.redact(eventId, new ApiCallback<Event>() {

        @Override
        public void onSuccess(final Event redactedEvent) {
            if (null != redactedEvent) {
                getUiHandler().post(new Runnable() {

                    @Override
                    public void run() {
                        // create a dummy redacted event to manage the redaction.
                        // some redacted events are not removed from the history but they are pruned.
                        Event redacterEvent = new Event();
                        redacterEvent.roomId = redactedEvent.roomId;
                        redacterEvent.redacts = redactedEvent.eventId;
                        redacterEvent.setType(Event.EVENT_TYPE_REDACTION);
                        onEvent(redacterEvent, EventTimeline.Direction.FORWARDS, mRoom.getLiveState());
                        if (null != mEventSendingListener) {
                            try {
                                mEventSendingListener.onMessageRedacted(redactedEvent);
                            } catch (Exception e) {
                                Log.e(LOG_TAG, "redactEvent fails : " + e.getMessage());
                            }
                        }
                    }
                });
            }
        }

        private void onError() {
            if (null != getActivity()) {
                Toast.makeText(getActivity(), getActivity().getString(R.string.could_not_redact), Toast.LENGTH_SHORT).show();
            }
        }

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

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

        @Override
        public void onUnexpectedError(Exception e) {
            onError();
        }
    });
}
Also used : MotionEvent(android.view.MotionEvent) Event(org.matrix.androidsdk.rest.model.Event) MatrixError(org.matrix.androidsdk.rest.model.MatrixError)

Example 23 with MatrixError

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

the class MatrixMessagesFragment method previewRoom.

/**
 * Trigger a room preview i.e trigger an initial sync before filling the message list.
 */
private void previewRoom() {
    Log.d(LOG_TAG, "Make a room preview of " + mRoom.getRoomId());
    if (null != mMatrixMessagesListener) {
        RoomPreviewData roomPreviewData = mMatrixMessagesListener.getRoomPreviewData();
        if (null != roomPreviewData) {
            if (null != roomPreviewData.getRoomResponse()) {
                Log.d(LOG_TAG, "A preview data is provided with sync response");
                RoomResponse roomResponse = roomPreviewData.getRoomResponse();
                // initialize the timeline with the initial sync response
                RoomSync roomSync = new RoomSync();
                roomSync.state = new RoomSyncState();
                roomSync.state.events = roomResponse.state;
                roomSync.timeline = new RoomSyncTimeline();
                roomSync.timeline.events = roomResponse.messages.chunk;
                roomSync.timeline.limited = true;
                roomSync.timeline.prevBatch = roomResponse.messages.end;
                mEventTimeline.handleJoinedRoomSync(roomSync, true);
                Log.d(LOG_TAG, "The room preview is done -> fill the room history");
                mHasPendingInitialHistory = true;
            } else {
                Log.d(LOG_TAG, "A preview data is provided with no sync response : assume that it is not possible to get a room preview");
                if (null != getActivity()) {
                    if (null != mMatrixMessagesListener) {
                        mMatrixMessagesListener.hideInitLoading();
                    }
                }
            }
            return;
        }
    }
    mSession.getRoomsApiClient().initialSync(mRoom.getRoomId(), new ApiCallback<RoomResponse>() {

        @Override
        public void onSuccess(RoomResponse roomResponse) {
            // initialize the timeline with the initial sync response
            RoomSync roomSync = new RoomSync();
            roomSync.state = new RoomSyncState();
            roomSync.state.events = roomResponse.state;
            roomSync.timeline = new RoomSyncTimeline();
            roomSync.timeline.events = roomResponse.messages.chunk;
            mEventTimeline.handleJoinedRoomSync(roomSync, true);
            Log.d(LOG_TAG, "The room preview is done -> fill the room history");
            requestInitialHistory();
        }

        private void onError(String errorMessage) {
            Log.e(LOG_TAG, "The room preview of " + mRoom.getRoomId() + "failed " + errorMessage);
            if (null != getActivity()) {
                getActivity().finish();
            }
        }

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

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

        @Override
        public void onUnexpectedError(Exception e) {
            onError(e.getLocalizedMessage());
        }
    });
}
Also used : RoomResponse(org.matrix.androidsdk.rest.model.sync.RoomResponse) RoomSync(org.matrix.androidsdk.rest.model.sync.RoomSync) RoomPreviewData(org.matrix.androidsdk.data.RoomPreviewData) RoomSyncState(org.matrix.androidsdk.rest.model.sync.RoomSyncState) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) RoomSyncTimeline(org.matrix.androidsdk.rest.model.sync.RoomSyncTimeline)

Example 24 with MatrixError

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

the class EventsRestClient method searchUsers.

/**
 * Search users with a patter,
 *
 * @param text          the text to search for.
 * @param limit         the maximum nbr of users in the response
 * @param userIdsFilter the userIds to exclude from the result
 * @param callback      the request callback
 */
public void searchUsers(final String text, final Integer limit, final Set<String> userIdsFilter, final ApiCallback<SearchUsersResponse> callback) {
    SearchUsersParams searchParams = new SearchUsersParams();
    searchParams.search_term = text;
    searchParams.limit = limit + ((null != userIdsFilter) ? userIdsFilter.size() : 0);
    final String uid = mSearchUsersPatternIdentifier = System.currentTimeMillis() + " " + text + " " + limit;
    final String description = "searchUsers";
    try {
        // don't retry to send the request
        // if the search fails, stop it
        mApi.searchUsers(searchParams, new RestAdapterCallback<SearchUsersRequestResponse>(description, null, new ApiCallback<SearchUsersRequestResponse>() {

            /**
             * 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(mSearchUsersPatternIdentifier, uid);
            }

            @Override
            public void onSuccess(SearchUsersRequestResponse aResponse) {
                if (isActiveRequest()) {
                    SearchUsersResponse response = new SearchUsersResponse();
                    response.limited = aResponse.limited;
                    response.results = new ArrayList<>();
                    Set<String> filter = (null != userIdsFilter) ? userIdsFilter : new HashSet<String>();
                    if (null != aResponse.results) {
                        for (SearchUsersRequestResponse.User user : aResponse.results) {
                            if ((null != user.user_id) && !filter.contains(user.user_id)) {
                                User addedUser = new User();
                                addedUser.user_id = user.user_id;
                                addedUser.avatar_url = user.avatar_url;
                                addedUser.displayname = user.display_name;
                                response.results.add(addedUser);
                            }
                        }
                    }
                    callback.onSuccess(response);
                    mSearchUsersPatternIdentifier = null;
                }
            }

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

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

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

            @Override
            public void onRetry() {
                searchUsers(text, limit, userIdsFilter, callback);
            }
        }));
    } catch (Throwable t) {
        callback.onUnexpectedError(new Exception(t));
    }
}
Also used : User(org.matrix.androidsdk.rest.model.User) ApiCallback(org.matrix.androidsdk.rest.callback.ApiCallback) SearchUsersParams(org.matrix.androidsdk.rest.model.search.SearchUsersParams) SearchUsersRequestResponse(org.matrix.androidsdk.rest.model.search.SearchUsersRequestResponse) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) SearchUsersResponse(org.matrix.androidsdk.rest.model.search.SearchUsersResponse)

Example 25 with MatrixError

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

the class EventsRestClient method searchMessagesByText.

/**
 * Search a text in room messages.
 *
 * @param text        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 searchMessagesByText(final String text, 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 = text;
    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);
    if (null != rooms) {
        searchEventParams.filter = new HashMap<>();
        searchEventParams.filter.put("rooms", rooms);
    }
    searchParams.search_categories = new HashMap<>();
    searchParams.search_categories.put("room_events", searchEventParams);
    final String description = "searchMessageText";
    final String uid = System.currentTimeMillis() + "";
    mSearchEventsPatternIdentifier = uid + text;
    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(mSearchEventsPatternIdentifier, uid + text);
            }

            @Override
            public void onSuccess(SearchResponse response) {
                if (isActiveRequest()) {
                    if (null != callback) {
                        callback.onSuccess(response);
                    }
                    mSearchEventsPatternIdentifier = null;
                }
            }

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

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

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

            @Override
            public void onRetry() {
                searchMessagesByText(text, 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) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) SearchResponse(org.matrix.androidsdk.rest.model.search.SearchResponse)

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