Projects >> android-frameworks-base-with-remote-control-service >>252b36379fedd0c91125679170a56d080d05ae9f

Chunk
Conflicting content
import android.content.ClipboardManager;
import android.content.ClippedData;
import android.content.Context;
<<<<<<< HEAD
=======
import android.content.Intent;
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.content.res.Resources;
Solution content
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.content.res.Resources;
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Import
Chunk
Conflicting content
            changed = bringTextIntoView();
        }

<<<<<<< HEAD
        if (mShouldStartSelectionActionMode) {
            startSelectionActionMode();
            mShouldStartSelectionActionMode = false;
=======
        if (mShouldStartTextSelectionMode) {
            startTextSelectionMode();
            mShouldStartTextSelectionMode = false;
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
        }
        mPreDrawState = PREDRAW_DONE;
        return !changed;
Solution content
            changed = bringTextIntoView();
        }

        if (mShouldStartSelectionActionMode) {
            startSelectionActionMode();
            mShouldStartSelectionActionMode = false;
        }
        mPreDrawState = PREDRAW_DONE;
        return !changed;
File
TextView.java
Developer's decision
Version 1
Kind of conflict
If statement
Method invocation
Chunk
Conflicting content
        }

        hideControllers();
<<<<<<< HEAD
        
=======

>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_CENTER:
                /*
Solution content
        }

        hideControllers();
        
        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_CENTER:
                /*
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Blank
Chunk
Conflicting content
            // needed by the cursor controller. Layout creation is deferred up to drawing. The
            // selection action mode will be started in onPreDraw().
            if (selStart != selEnd) {
<<<<<<< HEAD
                mShouldStartSelectionActionMode = true;
=======
                mShouldStartTextSelectionMode = true;
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
            }
        } else {
            if (mError != null) {
Solution content
            // needed by the cursor controller. Layout creation is deferred up to drawing. The
            // selection action mode will be started in onPreDraw().
            if (selStart != selEnd) {
                mShouldStartSelectionActionMode = true;
            }
        } else {
            if (mError != null) {
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Other
Chunk
Conflicting content
            onEndBatchEdit();

            hideInsertionPointCursorController();
<<<<<<< HEAD
            terminateSelectionActionMode();
=======
            terminateTextSelectionMode();
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
        }

        startStopMarquee(focused);
Solution content
            onEndBatchEdit();

            hideInsertionPointCursorController();
            terminateSelectionActionMode();
        }

        startStopMarquee(focused);
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Method invocation
Chunk
Conflicting content
    class CommitSelectionReceiver extends ResultReceiver {
        private final int mPrevStart, mPrevEnd;
        private final int mNewStart, mNewEnd;
<<<<<<< HEAD

=======
        
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
        public CommitSelectionReceiver(int mPrevStart, int mPrevEnd, int mNewStart, int mNewEnd) {
            super(getHandler());
            this.mPrevStart = mPrevStart;
Solution content
    class CommitSelectionReceiver extends ResultReceiver {
        private final int mPrevStart, mPrevEnd;
        private final int mNewStart, mNewEnd;

        public CommitSelectionReceiver(int mPrevStart, int mPrevEnd, int mNewStart, int mNewEnd) {
            super(getHandler());
            this.mPrevStart = mPrevStart;
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Blank
Chunk
Conflicting content
            this.mNewStart = mNewStart;
            this.mNewEnd = mNewEnd;
        }
<<<<<<< HEAD

=======
        
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            int start = mNewStart;
Solution content
            this.mNewStart = mNewStart;
            this.mNewEnd = mNewEnd;
        }

        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            int start = mNewStart;
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Blank
Chunk
Conflicting content
                        return;
                    } else {
                        // Tapping outside stops selection mode, if any
<<<<<<< HEAD
                        stopSelectionActionMode();
=======
                        stopTextSelectionMode();
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
                    }
                }
Solution content
                        return;
                    } else {
                        // Tapping outside stops selection mode, if any
                        stopSelectionActionMode();
                    }
                }
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Method invocation
Chunk
Conflicting content
            
            int oldSelStart = getSelectionStart();
            int oldSelEnd = getSelectionEnd();
<<<<<<< HEAD

=======
            
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
            if (mInsertionPointCursorController != null) {
                mInsertionPointCursorController.onTouchEvent(event);
            }
Solution content
            
            int oldSelStart = getSelectionStart();
            int oldSelEnd = getSelectionEnd();

            if (mInsertionPointCursorController != null) {
                mInsertionPointCursorController.onTouchEvent(event);
            }
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Blank
Chunk
Conflicting content
            }

            boolean handled = false;
<<<<<<< HEAD

=======
            
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
            if (mMovement != null) {
                handled |= mMovement.onTouchEvent(this, (Spannable) mText, event);
            }
Solution content
            }

            boolean handled = false;

            if (mMovement != null) {
                handled |= mMovement.onTouchEvent(this, (Spannable) mText, event);
            }
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Blank
Chunk
Conflicting content
                if (action == MotionEvent.ACTION_UP && isFocused() && !mScrolled) {
                    InputMethodManager imm = (InputMethodManager)
                            getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
<<<<<<< HEAD

                    final int newSelStart = getSelectionStart();
                    final int newSelEnd = getSelectionEnd();

=======
                    
                    final int newSelStart = getSelectionStart();
                    final int newSelEnd = getSelectionEnd();
                    
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
                    CommitSelectionReceiver csr = null;
                    if (newSelStart != oldSelStart || newSelEnd != oldSelEnd) {
                        csr = new CommitSelectionReceiver(oldSelStart, oldSelEnd,
Solution content
                if (action == MotionEvent.ACTION_UP && isFocused() && !mScrolled) {
                    InputMethodManager imm = (InputMethodManager)
                            getContext().getSystemService(Context.INPUT_METHOD_SERVICE);

                    final int newSelStart = getSelectionStart();
                    final int newSelEnd = getSelectionEnd();

                    CommitSelectionReceiver csr = null;
                    if (newSelStart != oldSelStart || newSelEnd != oldSelEnd) {
                        csr = new CommitSelectionReceiver(oldSelStart, oldSelEnd,
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Method invocation
Variable
Chunk
Conflicting content
                        csr = new CommitSelectionReceiver(oldSelStart, oldSelEnd,
                                newSelStart, newSelEnd);
                    }
<<<<<<< HEAD

=======
                    
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
                    handled |= imm.showSoftInput(this, 0, csr) && (csr != null);
                }
            }
Solution content
                        csr = new CommitSelectionReceiver(oldSelStart, oldSelEnd,
                                newSelStart, newSelEnd);
                    }

                    handled |= imm.showSoftInput(this, 0, csr) && (csr != null);
                }
            }
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Blank
Chunk
Conflicting content
            }
        } else {
            // Stop selection mode if the controller becomes unavailable.
<<<<<<< HEAD
            stopSelectionActionMode();
=======
            stopTextSelectionMode();
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
            mSelectionModifierCursorController = null;
        }
    }
Solution content
        }
    }
            }
        } else {
            // Stop selection mode if the controller becomes unavailable.
            stopSelectionActionMode();
            mSelectionModifierCursorController = null;
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Method invocation
Chunk
Conflicting content
                getSelectionStart() >= 0 &&
                getSelectionEnd() >= 0 &&
                ((ClipboardManager)getContext().getSystemService(Context.CLIPBOARD_SERVICE)).
<<<<<<< HEAD
                hasPrimaryClip());
=======
                hasText());
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
    }

    /**
Solution content
                getSelectionStart() >= 0 &&
                getSelectionEnd() >= 0 &&
                ((ClipboardManager)getContext().getSystemService(Context.CLIPBOARD_SERVICE)).
                hasPrimaryClip());
    }

    /**
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Other
Chunk
Conflicting content
                break;
            }
        }
<<<<<<< HEAD

        if (!hasLetter) {
            return -1;
        }

        // Two ints packed in a long
        return (((long) start) << 32) | end;
    }
=======

        if (!hasLetter) {
            return -1;
        }

        // Two ints packed in a long
        return (((long) start) << 32) | end;
    }
    
    private void selectCurrentWord() {
        // In case selection mode is started after an orientation change or after a select all,
        // use the current selection instead of creating one
        if (hasSelection()) {
            return;
        }

        int selectionStart, selectionEnd;

        SelectionModifierCursorController selectionModifierCursorController =
            ((SelectionModifierCursorController) mSelectionModifierCursorController);
        int minOffset = selectionModifierCursorController.getMinTouchOffset();
        int maxOffset = selectionModifierCursorController.getMaxTouchOffset();

        long wordLimits = getWordLimitsAt(minOffset);
        if (wordLimits >= 0) {
            selectionStart = (int) (wordLimits >>> 32);
        } else {
            selectionStart = Math.max(minOffset - 5, 0);
        }

        wordLimits = getWordLimitsAt(maxOffset);
        if (wordLimits >= 0) {
            selectionEnd = (int) (wordLimits & 0x00000000FFFFFFFFL);
        } else {
            selectionEnd = Math.min(maxOffset + 5, mText.length());
        }
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9

        Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
    }
Solution content
                break;
            }
        }

        if (!hasLetter) {
            return -1;
        }

        // Two ints packed in a long
        return (((long) start) << 32) | end;
    }
File
TextView.java
Developer's decision
Combination
Kind of conflict
Cast expression
Comment
If statement
Method invocation
Method signature
Return statement
Variable
Chunk
Conflicting content
        super.onCreateContextMenu(menu);
        boolean added = false;

<<<<<<< HEAD
        MenuHandler handler = new MenuHandler();

        if (mText instanceof Spanned) {
            int selStart = getSelectionStart();
            int selEnd = getSelectionEnd();

            int min = Math.min(selStart, selEnd);
            int max = Math.max(selStart, selEnd);

            URLSpan[] urls = ((Spanned) mText).getSpans(min, max,
                                                        URLSpan.class);
            if (urls.length == 1) {
                menu.add(0, ID_COPY_URL, 0,
                         com.android.internal.R.string.copyUrl).
                            setOnMenuItemClickListener(handler);

                added = true;
            }
        }
        

        // The context menu is not empty, which will prevent the selection mode from starting.
        // Add a entry to start it in the context menu.
        // TODO Does not handle the case where a subclass does not call super.thisMethod or
        // populates the menu AFTER this call.
        if (menu.size() > 0) {
            menu.add(0, ID_SELECTION_MODE, 0, com.android.internal.R.string.selectTextMode).
            setOnMenuItemClickListener(handler);
            added = true;
=======
        if (mIsInTextSelectionMode) {
            MenuHandler handler = new MenuHandler();
            
            if (canCut()) {
                menu.add(0, ID_CUT, 0, com.android.internal.R.string.cut).
                     setOnMenuItemClickListener(handler).
                     setAlphabeticShortcut('x');
            }

            if (canCopy()) {
                menu.add(0, ID_COPY, 0, com.android.internal.R.string.copy).
                     setOnMenuItemClickListener(handler).
                     setAlphabeticShortcut('c');
            }

            if (canPaste()) {
                menu.add(0, ID_PASTE, 0, com.android.internal.R.string.paste).
                     setOnMenuItemClickListener(handler).
                     setAlphabeticShortcut('v');
            }

            menu.add(0, ID_STOP_SELECTING_TEXT, 0, com.android.internal.R.string.stopSelectingText).
                 setOnMenuItemClickListener(handler);
            
            added = true;
        } else {
            /*
            if (!isFocused()) {
                if (isFocusable() && mInput != null) {
                    if (canCopy()) {
                        MenuHandler handler = new MenuHandler();
                        menu.add(0, ID_COPY, 0, com.android.internal.R.string.copy).
                             setOnMenuItemClickListener(handler).
                             setAlphabeticShortcut('c');
                        menu.setHeaderTitle(com.android.internal.R.string.editTextMenuTitle);
                    }
                }

                //return;
            }
             */
            MenuHandler handler = new MenuHandler();

            if (canSelectText()) {
                menu.add(0, ID_START_SELECTING_TEXT, 0, com.android.internal.R.string.selectText).
                setOnMenuItemClickListener(handler);
                added = true;
            }
            
            if (canSelectAll()) {
                menu.add(0, ID_SELECT_ALL, 0, com.android.internal.R.string.selectAll).
                     setOnMenuItemClickListener(handler).
                     setAlphabeticShortcut('a');
                added = true;
            }

            if (mText instanceof Spanned) {
                int selStart = getSelectionStart();
                int selEnd = getSelectionEnd();

                int min = Math.min(selStart, selEnd);
                int max = Math.max(selStart, selEnd);

                URLSpan[] urls = ((Spanned) mText).getSpans(min, max,
                        URLSpan.class);
                if (urls.length == 1) {
                    menu.add(0, ID_COPY_URL, 0, com.android.internal.R.string.copyUrl).
                         setOnMenuItemClickListener(handler);
                    added = true;
                }
            }
            
            if (canPaste()) {
                menu.add(0, ID_PASTE, 0, com.android.internal.R.string.paste).
                     setOnMenuItemClickListener(handler).
                     setAlphabeticShortcut('v');
            }

            if (isInputMethodTarget()) {
                menu.add(1, ID_SWITCH_INPUT_METHOD, 0, com.android.internal.R.string.inputMethod).
                     setOnMenuItemClickListener(handler);
                added = true;
            }
            String word = getWordForDictionary();
            if (word != null) {
                menu.add(1, ID_ADD_TO_DICTIONARY, 0,
                     getContext().getString(com.android.internal.R.string.addToDictionary, word)).
                     setOnMenuItemClickListener(handler);
                added = true;

            }
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
        }

        if (added) {
Solution content
        super.onCreateContextMenu(menu);
        boolean added = false;

        MenuHandler handler = new MenuHandler();

        if (mText instanceof Spanned) {
            int selStart = getSelectionStart();
            int selEnd = getSelectionEnd();

            int min = Math.min(selStart, selEnd);
            int max = Math.max(selStart, selEnd);

            URLSpan[] urls = ((Spanned) mText).getSpans(min, max,
                                                        URLSpan.class);
            if (urls.length == 1) {
                menu.add(0, ID_COPY_URL, 0,
                         com.android.internal.R.string.copyUrl).
                            setOnMenuItemClickListener(handler);

                added = true;
            }
        }
        
        // The context menu is not empty, which will prevent the selection mode from starting.
        // Add a entry to start it in the context menu.
        // TODO Does not handle the case where a subclass does not call super.thisMethod or
        // populates the menu AFTER this call.
        if (menu.size() > 0) {
            menu.add(0, ID_SELECTION_MODE, 0, com.android.internal.R.string.selectTextMode).
            setOnMenuItemClickListener(handler);
            added = true;
        }

        if (added) {
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Comment
If statement
Method invocation
Variable
Chunk
Conflicting content
        return imm != null && imm.isActive(this);
    }
    
<<<<<<< HEAD
    // Selection context mode
=======
    // Context menu entries
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
    private static final int ID_SELECT_ALL = android.R.id.selectAll;
    private static final int ID_CUT = android.R.id.cut;
    private static final int ID_COPY = android.R.id.copy;
Solution content
        return imm != null && imm.isActive(this);
    }
    
    // Selection context mode
    private static final int ID_SELECT_ALL = android.R.id.selectAll;
    private static final int ID_CUT = android.R.id.cut;
    private static final int ID_COPY = android.R.id.copy;
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Comment
Chunk
Conflicting content
        int min = 0;
        int max = mText.length();

<<<<<<< HEAD
        int min = Math.max(0, Math.min(selStart, selEnd));
        int max = Math.max(0, Math.max(selStart, selEnd));

        ClipboardManager clipboard = (ClipboardManager)getContext()
                .getSystemService(Context.CLIPBOARD_SERVICE);

        switch (id) {
            case ID_COPY_URL:
                MetaKeyKeyListener.stopSelecting(this, (Spannable) mText);

                URLSpan[] urls = ((Spanned) mText).getSpans(min, max, URLSpan.class);
                if (urls.length >= 1) {
                    ClippedData clip = null;
                    for (int i=0; i>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
                return true;
            }
Solution content
        int min = 0;
        int max = mText.length();
        
        if (isFocused()) {
            int selStart = getSelectionStart();
            int selEnd = getSelectionEnd();
            min = Math.max(0, Math.min(selStart, selEnd));
            max = Math.max(0, Math.max(selStart, selEnd));
        }

        ClipboardManager clipboard = (ClipboardManager)getContext()
                .getSystemService(Context.CLIPBOARD_SERVICE);

        switch (id) {
            case ID_COPY_URL:
                MetaKeyKeyListener.stopSelecting(this, (Spannable) mText);

                URLSpan[] urls = ((Spanned) mText).getSpans(min, max, URLSpan.class);
                if (urls.length >= 1) {
                    ClippedData clip = null;
                    for (int i=0; i
File
TextView.java
Developer's decision
Manual
Kind of conflict
Case statement
Cast expression
If statement
Method invocation
Return statement
Switch statement
Variable
Chunk
Conflicting content
    private void terminateSelectionActionMode() {
                return true;
            }

<<<<<<< HEAD
        return false;
    }

    @Override
    public boolean performLongClick() {
        if (super.performLongClick()) {
            mEatTouchRelease = true;
            return true;
        }
        
        if (startSelectionActionMode()) {
            performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
            mEatTouchRelease = true;
            return true;
        }

        return false;
    }

    private boolean touchPositionIsInSelection() {
        int selectionStart = getSelectionStart();
        int selectionEnd = getSelectionEnd();

        if (selectionStart == selectionEnd) {
            return false;
        }

        if (selectionStart > selectionEnd) {
            int tmp = selectionStart;
            selectionStart = selectionEnd;
            selectionEnd = tmp;
            Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
        }

        SelectionModifierCursorController selectionModifierCursorController =
            ((SelectionModifierCursorController) mSelectionModifierCursorController);
        int minOffset = selectionModifierCursorController.getMinTouchOffset();
        int maxOffset = selectionModifierCursorController.getMaxTouchOffset();

        return ((minOffset >= selectionStart) && (maxOffset < selectionEnd));
    }

    /**
     * Provides the callback used to start a selection action mode.
     *
     * @return A callback instance that will be used to start selection mode, or null if selection
     * mode is not available.
     */
    private ActionMode.Callback getActionModeCallback() {
        // Long press in the current selection.
        // Should initiate a drag. Return false, to rely on context menu for now.
        if (canSelectText() && !touchPositionIsInSelection()) {
            return new SelectionActionModeCallback();
        }
        return null;
    }

    /**
     *
     * @return true if the selection mode was actually started.
     */
    private boolean startSelectionActionMode() {
        if (mSelectionActionMode != null) {
            // Selection action mode is already started
            return false;
        }

        ActionMode.Callback actionModeCallback = getActionModeCallback();
        if (actionModeCallback != null) {
            mSelectionActionMode = startActionMode(actionModeCallback);
            return mSelectionActionMode != null;
        }

        return false;
    }

    /**
     * Same as {@link #stopSelectionActionMode()}, except that there is no cursor controller
     * fade out animation. Needed since the drawable and their alpha values are shared by all
     * TextViews. Switching from one TextView to another would fade the cursor controllers in the
     * new one otherwise.
     */
        stopSelectionActionMode();
        if (mSelectionModifierCursorController != null) {
            SelectionModifierCursorController selectionModifierCursorController =
                (SelectionModifierCursorController) mSelectionModifierCursorController;
            selectionModifierCursorController.cancelFadeOutAnimation();
        }
    }

    private void stopSelectionActionMode() {
        if (mSelectionActionMode != null) {
            mSelectionActionMode.finish();
        }
    }

    private class SelectionActionModeCallback implements ActionMode.Callback {

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            if (mSelectionModifierCursorController == null) {
                Log.w(LOG_TAG, "TextView has no selection controller. Action mode cancelled.");
                return false;
            }

            if (!requestFocus()) {
                return false;
            }

            mode.setTitle(mContext.getString(com.android.internal.R.string.textSelectionCABTitle));
            mode.setSubtitle(null);

            selectCurrentWord();

            boolean atLeastOne = false;

            if (canSelectAll()) {
                menu.add(0, ID_SELECT_ALL, 0, com.android.internal.R.string.selectAll).
                    setIcon(com.android.internal.R.drawable.ic_menu_chat_dashboard).
                    setAlphabeticShortcut('a');
                atLeastOne = true;
            }

            if (canCut()) {
                menu.add(0, ID_CUT, 0, com.android.internal.R.string.cut).
                    setIcon(com.android.internal.R.drawable.ic_menu_compose).
                    setAlphabeticShortcut('x');
                atLeastOne = true;
            }

            if (canCopy()) {
                menu.add(0, ID_COPY, 0, com.android.internal.R.string.copy).
                    setIcon(com.android.internal.R.drawable.ic_menu_attachment).
                    setAlphabeticShortcut('c');
                atLeastOne = true;
            }

            if (canPaste()) {
                menu.add(0, ID_PASTE, 0, com.android.internal.R.string.paste).
                        setIcon(com.android.internal.R.drawable.ic_menu_camera).
                        setAlphabeticShortcut('v');
                atLeastOne = true;
            }

            if (atLeastOne) {
                mSelectionModifierCursorController.show();
=======
            case ID_STOP_SELECTING_TEXT:
                stopTextSelectionMode();
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
                return true;
            } else {
                return false;
Solution content
                return true;
            }

        return false;
    }

    @Override
    public boolean performLongClick() {
        if (super.performLongClick()) {
            mEatTouchRelease = true;
            return true;
        }
        
        if (startSelectionActionMode()) {
            performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
            mEatTouchRelease = true;
            return true;
        }

        return false;
    }

    private boolean touchPositionIsInSelection() {
        int selectionStart = getSelectionStart();
        int selectionEnd = getSelectionEnd();

        if (selectionStart == selectionEnd) {
            return false;
        }

        if (selectionStart > selectionEnd) {
            int tmp = selectionStart;
            selectionStart = selectionEnd;
            selectionEnd = tmp;
            Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
        }

        SelectionModifierCursorController selectionModifierCursorController =
            ((SelectionModifierCursorController) mSelectionModifierCursorController);
        int minOffset = selectionModifierCursorController.getMinTouchOffset();
        int maxOffset = selectionModifierCursorController.getMaxTouchOffset();

        return ((minOffset >= selectionStart) && (maxOffset < selectionEnd));
    }

    /**
     * Provides the callback used to start a selection action mode.
     *
     * @return A callback instance that will be used to start selection mode, or null if selection
     * mode is not available.
     */
    private ActionMode.Callback getActionModeCallback() {
        // Long press in the current selection.
        // Should initiate a drag. Return false, to rely on context menu for now.
        if (canSelectText() && !touchPositionIsInSelection()) {
            return new SelectionActionModeCallback();
        }
        return null;
    }

    /**
     *
     * @return true if the selection mode was actually started.
     */
    private boolean startSelectionActionMode() {
        if (mSelectionActionMode != null) {
            // Selection action mode is already started
            return false;
        }
        ActionMode.Callback actionModeCallback = getActionModeCallback();
        if (actionModeCallback != null) {
            mSelectionActionMode = startActionMode(actionModeCallback);
            return mSelectionActionMode != null;
        }

        return false;
    }

    /**
     * Same as {@link #stopSelectionActionMode()}, except that there is no cursor controller
     * fade out animation. Needed since the drawable and their alpha values are shared by all
     * TextViews. Switching from one TextView to another would fade the cursor controllers in the
     * new one otherwise.
     */
    private void terminateSelectionActionMode() {
        stopSelectionActionMode();
        if (mSelectionModifierCursorController != null) {
            SelectionModifierCursorController selectionModifierCursorController =
                (SelectionModifierCursorController) mSelectionModifierCursorController;
            selectionModifierCursorController.cancelFadeOutAnimation();
        }
    }

    private void stopSelectionActionMode() {
        if (mSelectionActionMode != null) {
            mSelectionActionMode.finish();
        }
    }

    private class SelectionActionModeCallback implements ActionMode.Callback {

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            if (mSelectionModifierCursorController == null) {
                Log.w(LOG_TAG, "TextView has no selection controller. Action mode cancelled.");
                return false;
            }

            if (!requestFocus()) {
                return false;
            }

            mode.setTitle(mContext.getString(com.android.internal.R.string.textSelectionCABTitle));
            mode.setSubtitle(null);

            selectCurrentWord();

            boolean atLeastOne = false;

            if (canSelectAll()) {
                menu.add(0, ID_SELECT_ALL, 0, com.android.internal.R.string.selectAll).
                    setIcon(com.android.internal.R.drawable.ic_menu_chat_dashboard).
                    setAlphabeticShortcut('a');
                atLeastOne = true;
            }

            if (canCut()) {
                menu.add(0, ID_CUT, 0, com.android.internal.R.string.cut).
                    setIcon(com.android.internal.R.drawable.ic_menu_compose).
                    setAlphabeticShortcut('x');
                atLeastOne = true;
            }

            if (canCopy()) {
                menu.add(0, ID_COPY, 0, com.android.internal.R.string.copy).
                    setIcon(com.android.internal.R.drawable.ic_menu_attachment).
                    setAlphabeticShortcut('c');
                atLeastOne = true;
            }

            if (canPaste()) {
                menu.add(0, ID_PASTE, 0, com.android.internal.R.string.paste).
                        setIcon(com.android.internal.R.drawable.ic_menu_camera).
                        setAlphabeticShortcut('v');
                atLeastOne = true;
            }

            if (atLeastOne) {
                mSelectionModifierCursorController.show();
                return true;
            } else {
                return false;
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Annotation
Case statement
Class signature
Comment
If statement
Method declaration
Method invocation
Method signature
Return statement
Variable
Chunk
Conflicting content
            }
        }

<<<<<<< HEAD
        private void selectCurrentWord() {
            // In case selection mode is started after an orientation change, use the current
            // selection instead of creating one
            if (hasSelection()) {
                return;
            }

            int selectionStart, selectionEnd;

            SelectionModifierCursorController selectionModifierCursorController =
                ((SelectionModifierCursorController) mSelectionModifierCursorController);
            int minOffset = selectionModifierCursorController.getMinTouchOffset();
            int maxOffset = selectionModifierCursorController.getMaxTouchOffset();

            long wordLimits = getWordLimitsAt(minOffset);
            if (wordLimits >= 0) {
                selectionStart = (int) (wordLimits >>> 32);
            } else {
                selectionStart = Math.max(minOffset - 5, 0);
            }
            wordLimits = getWordLimitsAt(maxOffset);
            if (wordLimits >= 0) {
                selectionEnd = (int) (wordLimits & 0x00000000FFFFFFFFL);
            } else {
                selectionEnd = Math.min(maxOffset + 5, mText.length());
            }

            Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return true;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            final int itemId = item.getItemId();

            if (itemId == ID_SELECT_ALL) {
                Selection.setSelection((Spannable) mText, 0, mText.length());
                // Update controller positions after selection change.
                if (mSelectionModifierCursorController != null) {
                    mSelectionModifierCursorController.show();
                }
=======
            case ID_CUT:                
                clip.setText(mTransformed.subSequence(min, max));
                ((Editable) mText).delete(min, max);
                stopTextSelectionMode();
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
                return true;
            }
Solution content
            }
        }

        private void selectCurrentWord() {
            // In case selection mode is started after an orientation change, use the current
            // selection instead of creating one
            if (hasSelection()) {
                return;
            }

            int selectionStart, selectionEnd;

            SelectionModifierCursorController selectionModifierCursorController =
                ((SelectionModifierCursorController) mSelectionModifierCursorController);
            int minOffset = selectionModifierCursorController.getMinTouchOffset();
            int maxOffset = selectionModifierCursorController.getMaxTouchOffset();

            long wordLimits = getWordLimitsAt(minOffset);
            if (wordLimits >= 0) {
                selectionStart = (int) (wordLimits >>> 32);
            } else {
                selectionStart = Math.max(minOffset - 5, 0);
            }

            wordLimits = getWordLimitsAt(maxOffset);
            if (wordLimits >= 0) {
                selectionEnd = (int) (wordLimits & 0x00000000FFFFFFFFL);
            } else {
                selectionEnd = Math.min(maxOffset + 5, mText.length());
            }

            Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return true;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            final int itemId = item.getItemId();
            if (itemId == ID_SELECT_ALL) {
                Selection.setSelection((Spannable) mText, 0, mText.length());
                // Update controller positions after selection change.
                if (mSelectionModifierCursorController != null) {
                    mSelectionModifierCursorController.show();
                }
                return true;
            }
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Annotation
Case statement
Comment
If statement
Method declaration
Method invocation
Method signature
Variable
Chunk
Conflicting content
                return true;
            }

<<<<<<< HEAD
            ClipboardManager clipboard = (ClipboardManager) getContext().
                    getSystemService(Context.CLIPBOARD_SERVICE);

            int min = 0;
            int max = mText.length();

            if (isFocused()) {
                final int selStart = getSelectionStart();
                final int selEnd = getSelectionEnd();

                min = Math.max(0, Math.min(selStart, selEnd));
                max = Math.max(0, Math.max(selStart, selEnd));
            }

            switch (item.getItemId()) {
                case ID_PASTE:
                    ClippedData clip = clipboard.getPrimaryClip();
                    if (clip != null) {
                        boolean didfirst = false;
                        for (int i=0; i= 0) {
                    int time = (int) (System.currentTimeMillis() - mFadeOutTimerStart);
                    if (time <= FADE_OUT_DURATION) {
                        final int alpha = 255 * (FADE_OUT_DURATION - time) / FADE_OUT_DURATION;
                        mStartHandle.mDrawable.setAlpha(alpha);
                        mEndHandle.mDrawable.setAlpha(alpha);
                        mStartHandle.postInvalidateDelayed(30);
                        mEndHandle.postInvalidateDelayed(30);
                    } else {
                        mStartHandle.mDrawable.setAlpha(0);
                        mEndHandle.mDrawable.setAlpha(0);
                        mIsVisible = false;
                    }
                }
                mStartHandle.mDrawable.draw(canvas);
                mEndHandle.mDrawable.draw(canvas);
            }
        }

        public void updatePosition(int offset) {
            int selectionStart = getSelectionStart();
            int selectionEnd = getSelectionEnd();
=======
            case ID_COPY:
                clip.setText(mTransformed.subSequence(min, max));
                stopTextSelectionMode();
                return true;

            case ID_PASTE:
                CharSequence paste = clip.getText();

                if (paste != null) {
                    Selection.setSelection((Spannable) mText, max);
                    ((Editable) mText).replace(min, max, paste);
                    stopTextSelectionMode();
                }
                return true;

            case ID_COPY_URL:
                URLSpan[] urls = ((Spanned) mText).getSpans(min, max, URLSpan.class);
                if (urls.length == 1) {
                    clip.setText(urls[0].getURL());
                }
                return true;
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9

            // Handle the case where start and end are swapped, making sure start <= end
            if (mStartIsDragged) {
Solution content
                return true;
            }

            ClipboardManager clipboard = (ClipboardManager) getContext().
                    getSystemService(Context.CLIPBOARD_SERVICE);

            int min = 0;
            int max = mText.length();

            if (isFocused()) {
                final int selStart = getSelectionStart();
                final int selEnd = getSelectionEnd();

                min = Math.max(0, Math.min(selStart, selEnd));
                max = Math.max(0, Math.max(selStart, selEnd));
            }

            switch (item.getItemId()) {
                case ID_PASTE:
                    ClippedData clip = clipboard.getPrimaryClip();
                    if (clip != null) {
                        boolean didfirst = false;
                        for (int i=0; i= 0) {
                    int time = (int) (System.currentTimeMillis() - mFadeOutTimerStart);
                    if (time <= FADE_OUT_DURATION) {
                        final int alpha = 255 * (FADE_OUT_DURATION - time) / FADE_OUT_DURATION;
                        mStartHandle.mDrawable.setAlpha(alpha);
                        mEndHandle.mDrawable.setAlpha(alpha);
                        mStartHandle.postInvalidateDelayed(30);
                        mEndHandle.postInvalidateDelayed(30);
                    } else {
                        mStartHandle.mDrawable.setAlpha(0);
                        mEndHandle.mDrawable.setAlpha(0);
                        mIsVisible = false;
                    }
                }
                mStartHandle.mDrawable.draw(canvas);
                mEndHandle.mDrawable.draw(canvas);
            }
        }

        public void updatePosition(int offset) {
            int selectionStart = getSelectionStart();
            int selectionEnd = getSelectionEnd();

            // Handle the case where start and end are swapped, making sure start <= end
            if (mStartIsDragged) {
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Annotation
Attribute
Case statement
Cast expression
Class declaration
Class signature
Comment
If statement
Interface declaration
Method declaration
Method invocation
Method signature
Return statement
Switch statement
Variable
Chunk
Conflicting content
                        }
                        break;
                }
<<<<<<< HEAD
            }
        }

        /**
         * @param event
         */
        private void updateMinAndMaxOffsets(MotionEvent event) {
            int pointerCount = event.getPointerCount();
            for (int index = 0; index < pointerCount; index++) {
                final int x = (int) event.getX(index);
                final int y = (int) event.getY(index);
                int offset = getOffset(x, y);
                if (offset < mMinTouchOffset) mMinTouchOffset = offset;
                if (offset > mMaxTouchOffset) mMaxTouchOffset = offset;
=======
                return true;
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
            }
        }
Solution content
                        }
                        break;
                }
            }
        }

        /**
         * @param event
         */
        private void updateMinAndMaxOffsets(MotionEvent event) {
            int pointerCount = event.getPointerCount();
            for (int index = 0; index < pointerCount; index++) {
                final int x = (int) event.getX(index);
                final int y = (int) event.getY(index);
                int offset = getOffset(x, y);
                if (offset < mMinTouchOffset) mMinTouchOffset = offset;
                if (offset > mMaxTouchOffset) mMaxTouchOffset = offset;
            }
        }
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Cast expression
Comment
For statement
If statement
Method invocation
Method signature
Return statement
Variable
Chunk
Conflicting content
        if (super.performLongClick()) {
        }
    }

<<<<<<< HEAD
    private void hideInsertionPointCursorController() {
        if (mInsertionPointCursorController != null) {
            mInsertionPointCursorController.hide();
=======
    @Override
    public boolean performLongClick() {
            mEatTouchRelease = true;
            return true;
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
        }
    }
Solution content
    }

        }
    private void hideInsertionPointCursorController() {
        if (mInsertionPointCursorController != null) {
            mInsertionPointCursorController.hide();
        }
    }
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Annotation
Attribute
If statement
Method invocation
Method signature
Return statement
Chunk
Conflicting content
        if (x < 0) {
        }
    }

<<<<<<< HEAD

    @ViewDebug.ExportedProperty(category = "text")
=======
    private void startTextSelectionMode() {
        if (mSelectionModifierCursorController == null) {
            Log.w(LOG_TAG, "TextView has no selection controller. Action mode cancelled.");
            return;
        }

        if (!requestFocus()) {
            return;
        }

        selectCurrentWord();
        mSelectionModifierCursorController.show();
        mIsInTextSelectionMode = true;
    }
    
    /**
     * Same as {@link #stopTextSelectionMode()}, except that there is no cursor controller
     * fade out animation. Needed since the drawable and their alpha values are shared by all
     * TextViews. Switching from one TextView to another would fade the cursor controllers in the
     * new one otherwise.
     */
    private void terminateTextSelectionMode() {
        stopTextSelectionMode();
        if (mSelectionModifierCursorController != null) {
            SelectionModifierCursorController selectionModifierCursorController =
                (SelectionModifierCursorController) mSelectionModifierCursorController;
            selectionModifierCursorController.cancelFadeOutAnimation();
        }
    }

    private void stopTextSelectionMode() {
        if (mIsInTextSelectionMode) {
            Selection.setSelection((Spannable) mText, getSelectionEnd());
            if (mSelectionModifierCursorController != null) {
                mSelectionModifierCursorController.hide();
            }

            mIsInTextSelectionMode = false;
        }
    }

    /**
     * A CursorController instance can be used to control a cursor in the text.
     *
     * It can be passed to an {@link ArrowKeyMovementMethod} which can intercepts events
     * and send them to this object instead of the cursor.
     */
    public interface CursorController {
        /* Cursor fade-out animation duration, in milliseconds. */
        static final int FADE_OUT_DURATION = 400;

        /**
         * Makes the cursor controller visible on screen. Will be drawn by {@link #draw(Canvas)}.

         * See also {@link #hide()}.
         */
        public void show();

        /**
         * Hide the cursor controller from screen.
         * See also {@link #show()}.
         */
        public void hide();

        /**
         * Update the controller's position.
         */
        public void updatePosition(int offset);

        /**
         * The controller and the cursor's positions can be link by a fixed offset,
         * computed when the controller is touched, and then maintained as it moves
         * @return Horizontal offset between the controller and the cursor.
         */
        public float getOffsetX();

        /**
         * @return Vertical offset between the controller and the cursor.
         */
        public float getOffsetY();

        /**
         * This method is called by {@link #onTouchEvent(MotionEvent)} and gives the controller
         * a chance to become active and/or visible.
         * @param event The touch event
         */
        public void onTouchEvent(MotionEvent event);

        /**
         * Draws a visual representation of the controller on the canvas.
         *
         * Called at the end of {@link #draw(Canvas)}, in the content coordinates system.
         * @param canvas The Canvas used by this TextView.
         */
        public void draw(Canvas canvas);
    }

    private class Handle {
        Drawable mDrawable;
        // Vertical extension of the touch region
        int mTopExtension, mBottomExtension;
        // Position of the virtual finger position on screen
        int mHopSpotVertcalPosition;

        Handle(Drawable drawable) {
            mDrawable = drawable;
        }

        void positionAtCursor(final int offset, boolean bottom) {
            final int drawableWidth = mDrawable.getIntrinsicWidth();
            final int drawableHeight = mDrawable.getIntrinsicHeight();
            final int line = mLayout.getLineForOffset(offset);
            final int lineTop = mLayout.getLineTop(line);
            final int lineBottom = mLayout.getLineBottom(line);

            mHopSpotVertcalPosition = lineTop + (bottom ? (3 * (lineBottom - lineTop)) / 4 :
                (lineBottom - lineTop) / 4);

            final Rect bounds = sCursorControllerTempRect;
            bounds.left = (int) (mLayout.getPrimaryHorizontal(offset) - drawableWidth / 2.0);
            bounds.top = (bottom ? lineBottom : lineTop) - drawableHeight / 2;

            mTopExtension = bottom ? 0 : drawableHeight / 2;
            mBottomExtension = drawableHeight;

            // Extend touch region up when editing the last line of text (or a single line) so that
            // it is easier to grab.
            if (line == mLayout.getLineCount() - 1) {
                mTopExtension = (lineBottom - lineTop) - drawableHeight / 2;
            }

            bounds.right = bounds.left + drawableWidth;
            bounds.bottom = bounds.top + drawableHeight;

            int boundTopBefore = bounds.top;
            convertFromViewportToContentCoordinates(bounds);
            mHopSpotVertcalPosition += bounds.top - boundTopBefore;
            mDrawable.setBounds(bounds);
            postInvalidate();
        }

        boolean hasFingerOn(float x, float y) {
            // Simulate a 'fat finger' to ease grabbing of the controller.
            // Expands according to controller image size instead of using dip distance.
            // Assumes controller imager has a sensible size, proportionnal to screen density.
            final int drawableWidth = mDrawable.getIntrinsicWidth();
            final Rect fingerRect = sCursorControllerTempRect;
            fingerRect.set((int) (x - drawableWidth / 2.0),
                           (int) (y - mBottomExtension),
                           (int) (x + drawableWidth / 2.0),
                           (int) (y + mTopExtension));
            return Rect.intersects(mDrawable.getBounds(), fingerRect);
        }

        void postInvalidate() {
            final Rect bounds = mDrawable.getBounds();
            TextView.this.postInvalidate(bounds.left, bounds.top, bounds.right, bounds.bottom);
        }

        void postInvalidateDelayed(long delay) {
            final Rect bounds = mDrawable.getBounds();
            TextView.this.postInvalidateDelayed(delay, bounds.left, bounds.top,
                    bounds.right, bounds.bottom);
        }
    }

    class InsertionPointCursorController implements CursorController {
        private static final int DELAY_BEFORE_FADE_OUT = 2100;

        // Whether or not the cursor control is currently visible
        private boolean mIsVisible = false;
        // Starting time of the fade timer
        private long mFadeOutTimerStart;
        // The cursor controller image
        private final Handle mHandle;
        // Used to detect a tap (vs drag) on the controller
        private long mOnDownTimerStart;
            x = 0;
        // Offset between finger hot point on cursor controller and actual cursor
        private float mOffsetX, mOffsetY;

        InsertionPointCursorController() {
            Resources res = mContext.getResources();
            mHandle = new Handle(res.getDrawable(com.android.internal.R.drawable.text_select_handle));
        }

        public void show() {
            updateDrawablePosition();
            // Has to be done after updatePosition, so that previous position invalidate
            // in only done if necessary.
            mIsVisible = true;
        }

        public void hide() {
            if (mIsVisible) {
                long time = System.currentTimeMillis();
                // Start fading out, only if not already in progress
                if (time - mFadeOutTimerStart < DELAY_BEFORE_FADE_OUT) {
                    mFadeOutTimerStart = time - DELAY_BEFORE_FADE_OUT;
                    mHandle.postInvalidate();
                }
            }
        }

        public void draw(Canvas canvas) {
            if (mIsVisible) {
                int time = (int) (System.currentTimeMillis() - mFadeOutTimerStart);
                if (time <= DELAY_BEFORE_FADE_OUT) {
                    mHandle.postInvalidateDelayed(DELAY_BEFORE_FADE_OUT - time);
                } else {
                    time -= DELAY_BEFORE_FADE_OUT;
                    if (time <= FADE_OUT_DURATION) {
                        final int alpha = (int)
                        ((255.0 * (FADE_OUT_DURATION - time)) / FADE_OUT_DURATION);
                        mHandle.mDrawable.setAlpha(alpha);
                        mHandle.postInvalidateDelayed(30);
                    } else {
                        mHandle.mDrawable.setAlpha(0);
                        mIsVisible = false;
                    }
                }
                mHandle.mDrawable.draw(canvas);
            }
        }

        public void updatePosition(int offset) {
            if (offset == getSelectionStart()) {
                return; // No change, no need to redraw
            }
            Selection.setSelection((Spannable) mText, offset);
            updateDrawablePosition();
        }

        private void updateDrawablePosition() {
            if (mIsVisible) {
                // Clear previous cursor controller before bounds are updated
                mHandle.postInvalidate();
            }

            final int offset = getSelectionStart();

            if (offset < 0) {
                // Should never happen, safety check.
                Log.w(LOG_TAG, "Update cursor controller position called with no cursor");
                mIsVisible = false;
                return;
            }

            mHandle.positionAtCursor(offset, true);

            mFadeOutTimerStart = System.currentTimeMillis();
            mHandle.mDrawable.setAlpha(255);
        }

        public void onTouchEvent(MotionEvent event) {
            if (isFocused() && isTextEditable() && mIsVisible) {
                switch (event.getActionMasked()) {
                    case MotionEvent.ACTION_DOWN : {
                        final float x = event.getX();
                        final float y = event.getY();

                        if (mHandle.hasFingerOn(x, y)) {
                            show();

                            if (mMovement instanceof ArrowKeyMovementMethod) {
                                ((ArrowKeyMovementMethod)mMovement).setCursorController(this);
                            }

                            if (mParent != null) {
                                // Prevent possible scrollView parent from scrolling, so that
                                // we can use auto-scrolling.
                                mParent.requestDisallowInterceptTouchEvent(true);
                            }

                            final Rect bounds = mHandle.mDrawable.getBounds();
                            mOffsetX = (bounds.left + bounds.right) / 2.0f - x;
                            mOffsetY = mHandle.mHopSpotVertcalPosition - y;

                            mOnDownTimerStart = event.getEventTime();
                        }
                        break;
                    }

                    case MotionEvent.ACTION_UP : {
                        int time = (int) (event.getEventTime() - mOnDownTimerStart);

                        if (time <= ViewConfiguration.getTapTimeout()) {
                            // A tap on the controller (not a drag) will move the cursor
                            int offset = getOffset((int) event.getX(), (int) event.getY());
                            Selection.setSelection((Spannable) mText, offset);

                            // Modified by cancelLongPress and prevents the cursor from changing
                            mScrolled = false;
                        }
                        break;
                    }
                }
            }
        }

        public float getOffsetX() {
            return mOffsetX;
        }

        public float getOffsetY() {
            return mOffsetY;
        }
    }

    class SelectionModifierCursorController implements CursorController {
        // Whether or not the selection controls are currently visible
        private boolean mIsVisible = false;
        // Whether that start or the end of selection controller is dragged
        private boolean mStartIsDragged = false;
        // Starting time of the fade timer
        private long mFadeOutTimerStart;
        // The cursor controller images
        private final Handle mStartHandle, mEndHandle;
        // Offset between finger hot point on active cursor controller and actual cursor
        private float mOffsetX, mOffsetY;
        // The offsets of that last touch down event. Remembered to start selection there.
        private int mMinTouchOffset, mMaxTouchOffset;

        SelectionModifierCursorController() {
            Resources res = mContext.getResources();
            mStartHandle = new Handle(res.getDrawable(com.android.internal.R.drawable.text_select_handle));
            mEndHandle = new Handle(res.getDrawable(com.android.internal.R.drawable.text_select_handle));
        }
        public void show() {
            updateDrawablesPositions();
            // Has to be done after updatePosition, so that previous position invalidate
            // in only done if necessary.
            mIsVisible = true;
            mFadeOutTimerStart = -1;
            hideInsertionPointCursorController();
        }

        public void hide() {
            if (mIsVisible && (mFadeOutTimerStart < 0)) {
                mFadeOutTimerStart = System.currentTimeMillis();
                mStartHandle.postInvalidate();
                mEndHandle.postInvalidate();
            }
        }

        public void cancelFadeOutAnimation() {
            mIsVisible = false;
            mStartHandle.postInvalidate();
            mEndHandle.postInvalidate();
        }

        public void draw(Canvas canvas) {
            if (mIsVisible) {
                if (mFadeOutTimerStart >= 0) {
                    int time = (int) (System.currentTimeMillis() - mFadeOutTimerStart);
                    if (time <= FADE_OUT_DURATION) {
                        final int alpha = 255 * (FADE_OUT_DURATION - time) / FADE_OUT_DURATION;
                        mStartHandle.mDrawable.setAlpha(alpha);
                        mEndHandle.mDrawable.setAlpha(alpha);
                        mStartHandle.postInvalidateDelayed(30);
                        mEndHandle.postInvalidateDelayed(30);
                    } else {
                        mStartHandle.mDrawable.setAlpha(0);
                        mEndHandle.mDrawable.setAlpha(0);
                        mIsVisible = false;
                    }
                }
                mStartHandle.mDrawable.draw(canvas);
                mEndHandle.mDrawable.draw(canvas);
            }
        }

        public void updatePosition(int offset) {
            int selectionStart = getSelectionStart();
            int selectionEnd = getSelectionEnd();

            // Handle the case where start and end are swapped, making sure start <= end
            if (mStartIsDragged) {
                if (offset <= selectionEnd) {
                    if (selectionStart == offset) {
                        return; // no change, no need to redraw;
                    }
                    selectionStart = offset;
                } else {
                    selectionStart = selectionEnd;
                    selectionEnd = offset;
                    mStartIsDragged = false;
                }
            } else {
                if (offset >= selectionStart) {
                    if (selectionEnd == offset) {
                        return; // no change, no need to redraw;
                    }
                    selectionEnd = offset;
                } else {
                    selectionEnd = selectionStart;
                    selectionStart = offset;
                    mStartIsDragged = true;
                }
            }

            Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
            updateDrawablesPositions();
        }

        private void updateDrawablesPositions() {
            if (mIsVisible) {
                // Clear previous cursor controller before bounds are updated
                mStartHandle.postInvalidate();
                mEndHandle.postInvalidate();
            }

            final int selectionStart = getSelectionStart();
            final int selectionEnd = getSelectionEnd();

            if ((selectionStart < 0) || (selectionEnd < 0)) {
                // Should never happen, safety check.
                Log.w(LOG_TAG, "Update selection controller position called with no cursor");
                mIsVisible = false;
                return;
            }
            boolean oneLineSelection = mLayout.getLineForOffset(selectionStart) == mLayout.getLineForOffset(selectionEnd); 
            mStartHandle.positionAtCursor(selectionStart, oneLineSelection);
            mEndHandle.positionAtCursor(selectionEnd, true);

            mStartHandle.mDrawable.setAlpha(255);
            mEndHandle.mDrawable.setAlpha(255);
        }

        public void onTouchEvent(MotionEvent event) {
            if (isTextEditable()) {
                switch (event.getActionMasked()) {
                    case MotionEvent.ACTION_DOWN:
                        final int x = (int) event.getX();
                        final int y = (int) event.getY();

                        // Remember finger down position, to be able to start selection from there
                        mMinTouchOffset = mMaxTouchOffset = getOffset(x, y);

                        if (mIsVisible) {
                            if (mMovement instanceof ArrowKeyMovementMethod) {
                                boolean isOnStart = mStartHandle.hasFingerOn(x, y);
                                boolean isOnEnd = mEndHandle.hasFingerOn(x, y);
                                if (isOnStart || isOnEnd) {
                                    if (mParent != null) {
                                        // Prevent possible scrollView parent from scrolling, so
                                        // that we can use auto-scrolling.
                                        mParent.requestDisallowInterceptTouchEvent(true);
                                    }

                                    // In case both controllers are under finger (very small
                                    // selection region), arbitrarily pick end controller.
                                    mStartIsDragged = !isOnEnd;
                                    final Handle draggedHandle = mStartIsDragged ? mStartHandle : mEndHandle;
                                    final Rect bounds = draggedHandle.mDrawable.getBounds();
                                    mOffsetX = (bounds.left + bounds.right) / 2.0f - x;
                                    mOffsetY = draggedHandle.mHopSpotVertcalPosition - y;

                                    ((ArrowKeyMovementMethod)mMovement).setCursorController(this);
                                }
                            }
                        }
                        break;

                    case MotionEvent.ACTION_POINTER_DOWN:
                    case MotionEvent.ACTION_POINTER_UP:
                        // Handle multi-point gestures. Keep min and max offset positions.
                        // Only activated for devices that correctly handle multi-touch.
                        if (mContext.getPackageManager().hasSystemFeature(
                                PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT)) {
                            updateMinAndMaxOffsets(event);
                        }
                        break;
                }
            }
        }

        /**
         * @param event
         */
        private void updateMinAndMaxOffsets(MotionEvent event) {
            int pointerCount = event.getPointerCount();
            for (int index = 0; index < pointerCount; index++) {
                final int x = (int) event.getX(index);
                final int y = (int) event.getY(index);
                int offset = getOffset(x, y);
                if (offset < mMinTouchOffset) mMinTouchOffset = offset;
                if (offset > mMaxTouchOffset) mMaxTouchOffset = offset;
            }
        }

        public int getMinTouchOffset() {
            return mMinTouchOffset;
        }

        public int getMaxTouchOffset() {
            return mMaxTouchOffset;
        }

        public float getOffsetX() {
            return mOffsetX;
        }

        public float getOffsetY() {
            return mOffsetY;
        }

        /**
         * @return true iff this controller is currently used to move the selection start.
         */
        public boolean isSelectionStartDragged() {
            return mIsVisible && mStartIsDragged;
        }
    }

    private void hideInsertionPointCursorController() {
        if (mInsertionPointCursorController != null) {
            mInsertionPointCursorController.hide();
        }
    }

    private void hideControllers() {
        hideInsertionPointCursorController();
        stopTextSelectionMode();
    }

    /**
     * Get the offset character closest to the specified absolute position.
     *
     * @param x The horizontal absolute position of a point on screen
     * @param y The vertical absolute position of a point on screen
     * @return the character offset for the character whose position is closest to the specified
     *  position. Returns -1 if there is no layout.
     *
     * @hide
     */
    public int getOffset(int x, int y) {
        x -= getTotalPaddingLeft();
        y -= getTotalPaddingTop();

        // Clamp the position to inside of the view.
        } else if (x >= (getWidth() - getTotalPaddingRight())) {
            x = getWidth()-getTotalPaddingRight() - 1;
        }
        if (y < 0) {
            y = 0;
        } else if (y >= (getHeight() - getTotalPaddingBottom())) {
            y = getHeight()-getTotalPaddingBottom() - 1;
        }

        x += getScrollX();
        y += getScrollY();

        Layout layout = getLayout();
        if (layout != null) {
            final int line = layout.getLineForVertical(y);
            final int offset = layout.getOffsetForHorizontal(line, x);
            return offset;
        } else {
            return -1;
        }
    }

    @ViewDebug.ExportedProperty
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
    private CharSequence            mText;
    private CharSequence            mTransformed;
    private BufferType              mBufferType = BufferType.NORMAL;
Solution content
        }
    }


    @ViewDebug.ExportedProperty(category = "text")
    private CharSequence            mText;
    private CharSequence            mTransformed;
    private BufferType              mBufferType = BufferType.NORMAL;
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Annotation
Class declaration
Comment
Interface declaration
Method declaration
Chunk
Conflicting content
    // Cursor Controllers. Null when disabled.
    private CursorController        mInsertionPointCursorController;
    private CursorController        mSelectionModifierCursorController;
<<<<<<< HEAD
    private boolean                 mShouldStartSelectionActionMode = false;
    private ActionMode              mSelectionActionMode;
=======
    private boolean                 mShouldStartTextSelectionMode = false;
    private boolean                 mIsInTextSelectionMode = false;
>>>>>>> a842d143d2dcad07906830a30deaf0ffce86f5d9
    // Created once and shared by different CursorController helper methods.
    // Only one cursor controller is active at any time which prevent race conditions.
    private static Rect             sCursorControllerTempRect = new Rect();
Solution content
    // Cursor Controllers. Null when disabled.
    private CursorController        mInsertionPointCursorController;
    private CursorController        mSelectionModifierCursorController;
    private boolean                 mShouldStartSelectionActionMode = false;
    private ActionMode              mSelectionActionMode;
    // Created once and shared by different CursorController helper methods.
    // Only one cursor controller is active at any time which prevent race conditions.
    private static Rect             sCursorControllerTempRect = new Rect();
File
TextView.java
Developer's decision
Version 1
Kind of conflict
Attribute