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

Commit 93d64c8a authored by Joanne Chung's avatar Joanne Chung Committed by Automerger Merge Worker
Browse files

Merge "Fix app crash if the selection is from reverse direction." am: 769acc45

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1355582

Change-Id: Ic96a92523730356672a6146d3e4566dba5ce4302
parents b8422721 769acc45
Loading
Loading
Loading
Loading
+55 −17
Original line number Diff line number Diff line
@@ -104,17 +104,44 @@ public final class SelectionActionModeHelper {
        }
    }

    /**
     * Swap the selection index if the start index is greater than end index.
     *
     * @return the swap result, index 0 is the start index and index 1 is the end index.
     */
    private static int[] sortSelctionIndices(int selectionStart, int selectionEnd) {
        if (selectionStart < selectionEnd) {
            return new int[]{selectionStart, selectionEnd};
        }
        return new int[]{selectionEnd, selectionStart};
    }

    /**
     * The {@link TextView} selection start and end index may not be sorted, this method will swap
     * the {@link TextView} selection index if the start index is greater than end index.
     *
     * @param textView the selected TextView.
     * @return the swap result, index 0 is the start index and index 1 is the end index.
     */
    private static int[] sortSelctionIndicesFromTextView(TextView textView) {
        int selectionStart = textView.getSelectionStart();
        int selectionEnd = textView.getSelectionEnd();

        return sortSelctionIndices(selectionStart, selectionEnd);
    }

    /**
     * Starts Selection ActionMode.
     */
    public void startSelectionActionModeAsync(boolean adjustSelection) {
        // Check if the smart selection should run for editable text.
        adjustSelection &= getTextClassificationSettings().isSmartSelectionEnabled();
        int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView);

        mSelectionTracker.onOriginalSelection(
                getText(mTextView),
                mTextView.getSelectionStart(),
                mTextView.getSelectionEnd(),
                sortedSelectionIndices[0],
                sortedSelectionIndices[1],
                false /*isLink*/);
        cancelAsyncTask();
        if (skipTextClassification()) {
@@ -139,12 +166,14 @@ public final class SelectionActionModeHelper {
     * Starts Link ActionMode.
     */
    public void startLinkActionModeAsync(int start, int end) {
        mSelectionTracker.onOriginalSelection(getText(mTextView), start, end, true /*isLink*/);
        int[] indexResult = sortSelctionIndices(start, end);
        mSelectionTracker.onOriginalSelection(getText(mTextView), indexResult[0], indexResult[1],
                true /*isLink*/);
        cancelAsyncTask();
        if (skipTextClassification()) {
            startLinkActionMode(null);
        } else {
            resetTextClassificationHelper(start, end);
            resetTextClassificationHelper(indexResult[0], indexResult[1]);
            mTextClassificationAsyncTask = new TextClassificationAsyncTask(
                    mTextView,
                    mTextClassificationHelper.getTimeoutDuration(),
@@ -173,19 +202,23 @@ public final class SelectionActionModeHelper {

    /** Reports a selection action event. */
    public void onSelectionAction(int menuItemId, @Nullable String actionLabel) {
        int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView);
        mSelectionTracker.onSelectionAction(
                mTextView.getSelectionStart(), mTextView.getSelectionEnd(),
                sortedSelectionIndices[0], sortedSelectionIndices[1],
                getActionType(menuItemId), actionLabel, mTextClassification);
    }

    public void onSelectionDrag() {
        int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView);
        mSelectionTracker.onSelectionAction(
                mTextView.getSelectionStart(), mTextView.getSelectionEnd(),
                sortedSelectionIndices[0], sortedSelectionIndices[1],
                SelectionEvent.ACTION_DRAG, /* actionLabel= */ null, mTextClassification);
    }

    public void onTextChanged(int start, int end) {
        mSelectionTracker.onTextChanged(start, end, mTextClassification);
        int[] sortedSelectionIndices = sortSelctionIndices(start, end);
        mSelectionTracker.onTextChanged(sortedSelectionIndices[0], sortedSelectionIndices[1],
                mTextClassification);
    }

    public boolean resetSelection(int textIndex) {
@@ -302,9 +335,10 @@ public final class SelectionActionModeHelper {
            startSelectionActionMode(startSelectionResult);
        };
        // TODO do not trigger the animation if the change included only non-printable characters
        int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView);
        final boolean didSelectionChange =
                result != null && (mTextView.getSelectionStart() != result.mStart
                        || mTextView.getSelectionEnd() != result.mEnd);
                result != null && (sortedSelectionIndices[0] != result.mStart
                        || sortedSelectionIndices[1] != result.mEnd);

        if (!didSelectionChange) {
            onAnimationEndCallback.run();
@@ -454,16 +488,18 @@ public final class SelectionActionModeHelper {
        if (actionMode != null) {
            actionMode.invalidate();
        }
        final int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView);
        mSelectionTracker.onSelectionUpdated(
                mTextView.getSelectionStart(), mTextView.getSelectionEnd(), mTextClassification);
                sortedSelectionIndices[0], sortedSelectionIndices[1], mTextClassification);
        mTextClassificationAsyncTask = null;
    }

    private void resetTextClassificationHelper(int selectionStart, int selectionEnd) {
        if (selectionStart < 0 || selectionEnd < 0) {
            // Use selection indices
            selectionStart = mTextView.getSelectionStart();
            selectionEnd = mTextView.getSelectionEnd();
            int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView);
            selectionStart = sortedSelectionIndices[0];
            selectionEnd = sortedSelectionIndices[1];
        }
        mTextClassificationHelper.init(
                mTextView::getTextClassifier,
@@ -603,10 +639,11 @@ public final class SelectionActionModeHelper {
                mAllowReset = false;
                boolean selected = editor.selectCurrentWord();
                if (selected) {
                    mSelectionStart = editor.getTextView().getSelectionStart();
                    mSelectionEnd = editor.getTextView().getSelectionEnd();
                    final int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(textView);
                    mSelectionStart = sortedSelectionIndices[0];
                    mSelectionEnd = sortedSelectionIndices[1];
                    mLogger.logSelectionAction(
                            textView.getSelectionStart(), textView.getSelectionEnd(),
                            sortedSelectionIndices[0], sortedSelectionIndices[1],
                            SelectionEvent.ACTION_RESET,
                            /* actionLabel= */ null, /* classification= */ null);
                }
@@ -1179,8 +1216,9 @@ public final class SelectionActionModeHelper {

        SelectionResult(int start, int end,
                @Nullable TextClassification classification, @Nullable TextSelection selection) {
            mStart = start;
            mEnd = end;
            int[] sortedIndices = sortSelctionIndices(start, end);
            mStart = sortedIndices[0];
            mEnd = sortedIndices[1];
            mClassification = classification;
            mSelection = selection;
        }