Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 08eb30df authored by Stephen Bird's avatar Stephen Bird Committed by Clark Scheff
Browse files

Editor: Handle content uri's in the editor

Previously, files opened that were not contained
inside the /data/media partition were considered
invalid.

Repo steps:
- Open email with .txt attachment
- Open attachment with Editor

This also fixes similar issues all across the
system where content uri's would not open in
editor. Previously they would report that the
user needed to gain root access.

Change-Id: I15aa3fd81ae261f66920d253d6adebe28cf28e66
(cherry picked from commit e09d8433)
REF: CYNGNOS-512
parent 1eaf8a99
Loading
Loading
Loading
Loading
+211 −58
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.util.ArrayList;
@@ -1000,6 +1001,11 @@ public class EditorActivity extends Activity implements TextWatcher {
        this.mReadOnly = false;

        // Read the intent and check that is has a valid request
        Intent fileIntent = getIntent();
        if (fileIntent.getData().getScheme().equals("content")) {
            asyncReadContentURI(fileIntent.getData());
        } else {
            // File Scheme URI's
            String path = uriToPath(this, getIntent().getData());
            if (path == null || path.length() == 0) {
                DialogHelper.showToast(
@@ -1015,15 +1021,9 @@ public class EditorActivity extends Activity implements TextWatcher {
            try {
                this.mFso = CommandHelper.getFileInfo(this, path, true, null);
                if (this.mFso == null) {
                DialogHelper.showToast(
                        this, R.string.editor_file_not_found_msg, Toast.LENGTH_SHORT);
                return;
                }
            } catch (Exception e) {
                Log.e(TAG, "Failed to get file reference", e); //$NON-NLS-1$
            DialogHelper.showToast(
                    this, R.string.editor_file_not_found_msg, Toast.LENGTH_SHORT);
            return;
            }

            // Check that we can handle the length of the file (by device)
@@ -1072,6 +1072,159 @@ public class EditorActivity extends Activity implements TextWatcher {
                        });
            }
        }
    }

    /**
     * Method that does the read of a content uri in the background
     * @hide
     */
    void asyncReadContentURI(Uri uri) {
        // Do the load of the file
        AsyncTask<Uri, Integer, Boolean> mReadTask =
                new AsyncTask<Uri, Integer, Boolean>() {

                    private Exception mCause;
                    private boolean changeToBinaryMode;
                    private boolean changeToDisplaying;
                    private String tempText;

                    @Override
                    protected void onPreExecute() {
                        // Show the progress
                        this.changeToBinaryMode = false;
                        this.changeToDisplaying = false;
                        doProgress(true, 0);
                    }

                    @Override
                    protected Boolean doInBackground(Uri... params) {

                        // Only one argument (the file to open)
                        Uri fso = params[0];
                        this.mCause = null;

                        // Read the file in an async listener
                        try {

                            publishProgress(Integer.valueOf(0));

                            InputStream is = getContentResolver().openInputStream(fso);

                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
                            int readBytes;
                            byte[] buffer = new byte[1024];
                            try {
                                while ((readBytes = is.read(buffer, 0, buffer.length)) != -1) {
                                    baos.write(buffer, 0, readBytes);
                                    publishProgress(
                                            Integer.valueOf((readBytes * 100) / buffer.length));
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                                return Boolean.FALSE;
                            }

                            // 100%
                            publishProgress(new Integer(100));
                            tempText = new String(baos.toByteArray(), "UTF-8");
                            Log.i(TAG, "Bytes read: " + baos.toByteArray().length); //$NON-NLS-1$

                            // 100%
                            this.changeToDisplaying = true;
                            publishProgress(new Integer(0));

                        } catch (Exception e) {
                            this.mCause = e;
                            return Boolean.FALSE;
                        }

                        return Boolean.TRUE;

                    }

                    @Override
                    protected void onProgressUpdate(Integer... values) {
                        // Do progress
                        doProgress(true, values[0].intValue());
                    }

                    @Override
                    protected void onPostExecute(Boolean result) {
                        final EditorActivity activity = EditorActivity.this;
                        // Is error?
                        if (!result.booleanValue()) {
                            if (this.mCause != null) {
                                ExceptionUtil.translateException(activity, this.mCause);
                                activity.mEditor.setEnabled(false);
                            }
                        } else {
                            // Now we have the buffer, set the text of the editor
                            activity.mEditor.setText(
                                    tempText, BufferType.EDITABLE);

                            // Highlight editor text syntax
                            if (activity.mSyntaxHighlight &&
                                    activity.mSyntaxHighlightProcessor != null) {
                                try {
                                    activity.mSyntaxHighlightProcessor.process(
                                            activity.mEditor.getText());
                                } catch (Exception ex) {
                                    // An error in a syntax library, should not break down app.
                                    Log.e(TAG, "Syntax highlight failed.", ex); //$NON-NLS-1$
                                }
                            }

                            setDirty(false);
                            activity.mEditor.setEnabled(!activity.mReadOnly);

                            // Notify read-only mode
                            if (activity.mReadOnly) {
                                DialogHelper.showToast(
                                        activity,
                                        R.string.editor_read_only_mode,
                                        Toast.LENGTH_SHORT);
                            }
                        }

                        doProgress(false, 0);
                    }

                    @Override
                    protected void onCancelled() {
                        // Hide the progress
                        doProgress(false, 0);
                    }

                    /**
                     * Method that update the progress status
                     *
                     * @param visible If the progress bar need to be hidden
                     * @param progress The progress
                     */
                    private void doProgress(boolean visible, int progress) {
                        final EditorActivity activity = EditorActivity.this;

                        // Show the progress bar
                        activity.mProgressBar.setProgress(progress);
                        activity.mProgress.setVisibility(visible ? View.VISIBLE : View.GONE);

                        if (this.changeToBinaryMode) {
                            mWordWrapView.setVisibility(View.GONE);
                            mNoWordWrapView.setVisibility(View.GONE);
                            mBinaryEditor.setVisibility(View.VISIBLE);

                            // Show hex dumping text
                            activity.mProgressBarMsg.setText(R.string.dumping_message);
                            this.changeToBinaryMode = false;
                        }
                        else if (this.changeToDisplaying) {
                            activity.mProgressBarMsg.setText(R.string.displaying_message);
                            this.changeToDisplaying = false;
                        }
                    }
                };
        mReadTask.execute(uri);
    }

    /**
     * Method that does the read of the file in background