Clean up chips

- Don't reset selection when we manually change selection due
  to selecting a chip. We need this selection index to make
  backspace properly delete the correct chip.
- Remove selected chips code because we now use the popup for
  selected indicator.
- Fix accessibility SDK (didn't crash previously because with
  SDK < 16 mIsAccessibilityOn is always false anyway).
- Clean up various warnings throughout RecipientEditTextView.

b/18682890

Change-Id: Ided53c0ea29532262c1f592798381ed9bc704fc0
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index be838bf..8cc5470 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -20,7 +20,6 @@
             <enum name="start" value="1" />
         </attr>
         <attr name="chipBackground" format="reference" />
-        <attr name="chipBackgroundPressed" format="reference" />
         <attr name="chipDelete" format="reference" />
         <attr name="chipFontSize" format="reference" />
         <attr name="chipHeight" format="reference" />
diff --git a/src/com/android/ex/chips/DropdownChipLayouter.java b/src/com/android/ex/chips/DropdownChipLayouter.java
index f88ea7d..a3b809c 100644
--- a/src/com/android/ex/chips/DropdownChipLayouter.java
+++ b/src/com/android/ex/chips/DropdownChipLayouter.java
@@ -220,18 +220,18 @@
         }
         if (drawable == null) {
             view.setVisibility(View.GONE);
-        }
-
-        view.setImageDrawable(drawable);
-        if (mDeleteListener != null) {
-            view.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View view) {
-                    if (drawable.getCurrent() != null) {
-                        mDeleteListener.onChipDelete();
+        } else {
+            view.setImageDrawable(drawable);
+            if (mDeleteListener != null) {
+                view.setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View view) {
+                        if (drawable.getCurrent() != null) {
+                            mDeleteListener.onChipDelete();
+                        }
                     }
-                }
-            });
+                });
+            }
         }
     }
 
diff --git a/src/com/android/ex/chips/RecipientEditTextView.java b/src/com/android/ex/chips/RecipientEditTextView.java
index bae6058..dd83360 100644
--- a/src/com/android/ex/chips/RecipientEditTextView.java
+++ b/src/com/android/ex/chips/RecipientEditTextView.java
@@ -17,6 +17,7 @@
 
 package com.android.ex.chips;
 
+import android.annotation.TargetApi;
 import android.app.Dialog;
 import android.content.ClipData;
 import android.content.ClipDescription;
@@ -47,6 +48,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.Parcelable;
+import android.support.annotation.NonNull;
 import android.text.Editable;
 import android.text.InputType;
 import android.text.Layout;
@@ -152,7 +154,6 @@
     private Drawable mChipBackground = null;
     private Drawable mChipDelete = null;
     private Drawable mInvalidChipBackground;
-    private Drawable mChipBackgroundPressed;
 
     // Possible attr overrides
     private float mChipHeight;
@@ -307,7 +308,6 @@
     }
 
     private void setupPopupWindow(ListPopupWindow popup) {
-        popup.setModal(true);
         popup.setOnDismissListener(new PopupWindow.OnDismissListener() {
             @Override
             public void onDismiss() {
@@ -391,7 +391,7 @@
     }
 
     @Override
-    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
+    public InputConnection onCreateInputConnection(@NonNull EditorInfo outAttrs) {
         InputConnection connection = super.onCreateInputConnection(outAttrs);
         int imeActions = outAttrs.imeOptions&EditorInfo.IME_MASK_ACTION;
         if ((imeActions&EditorInfo.IME_ACTION_DONE) != 0) {
@@ -428,7 +428,7 @@
     public List<RecipientEntry> getSelectedRecipients() {
         DrawableRecipientChip[] chips =
                 getText().getSpans(0, getText().length(), DrawableRecipientChip.class);
-        List<RecipientEntry> results = new ArrayList();
+        List<RecipientEntry> results = new ArrayList<RecipientEntry>();
         if (chips == null) {
             return results;
         }
@@ -444,8 +444,9 @@
     public void onSelectionChanged(int start, int end) {
         // When selection changes, see if it is inside the chips area.
         // If so, move the cursor back after the chips again.
+        // Only exception is when we change the selection due to a selected chip.
         DrawableRecipientChip last = getLastChip();
-        if (last != null && start < getSpannable().getSpanEnd(last)) {
+        if (mSelectedChip == null && last != null && start < getSpannable().getSpanEnd(last)) {
             // Grab the last chip and set the cursor to after it.
             setSelection(Math.min(getSpannable().getSpanEnd(last) + 1, getText().length()));
         }
@@ -515,7 +516,7 @@
     }
 
     @Override
-    public <T extends ListAdapter & Filterable> void setAdapter(T adapter) {
+    public <T extends ListAdapter & Filterable> void setAdapter(@NonNull T adapter) {
         super.setAdapter(adapter);
         BaseRecipientAdapter baseAdapter = (BaseRecipientAdapter) adapter;
         baseAdapter.registerUpdateObserver(new BaseRecipientAdapter.EntriesUpdatedObserver() {
@@ -546,8 +547,9 @@
         baseAdapter.setDropdownChipLayouter(mDropdownChipLayouter);
     }
 
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
     private void announceForAccessibilityCompat(String text) {
-        if (mIsAccessibilityOn && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+        if (mIsAccessibilityOn && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
             final ViewParent parent = getParent();
             if (parent != null) {
                 AccessibilityEvent event = AccessibilityEvent.obtain(
@@ -674,25 +676,7 @@
      * @param contact The recipient entry to pull data from.
      * @param paint The paint to use to draw the bitmap.
      */
-    private Bitmap createSelectedChip(RecipientEntry contact, TextPaint paint) {
-        paint.setColor(mSelectedChipTextColor);
-        final ChipBitmapContainer bitmapContainer = createChipBitmap(contact, paint,
-                mChipBackgroundPressed, mSelectedChipBackgroundColor);
-
-        if (bitmapContainer.loadIcon) {
-            loadAvatarIcon(contact, bitmapContainer);
-        }
-
-        return bitmapContainer.bitmap;
-    }
-
-    /**
-     * Creates a bitmap of the given contact on a selected chip.
-     *
-     * @param contact The recipient entry to pull data from.
-     * @param paint The paint to use to draw the bitmap.
-     */
-    private Bitmap createUnselectedChip(RecipientEntry contact, TextPaint paint) {
+    private Bitmap createChipBitmap(RecipientEntry contact, TextPaint paint) {
         paint.setColor(getDefaultChipTextColor(contact));
         ChipBitmapContainer bitmapContainer = createChipBitmap(contact, paint,
                 getChipBackground(contact), getDefaultChipBackgroundColor(contact));
@@ -787,8 +771,8 @@
      * the layout direction is LTR or RTL.
      */
     private boolean shouldPositionAvatarOnRight() {
-        final boolean isRtl = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 ?
-                getLayoutDirection() == LAYOUT_DIRECTION_RTL : false;
+        final boolean isRtl = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 &&
+                getLayoutDirection() == LAYOUT_DIRECTION_RTL;
         final boolean assignedPosition = mAvatarPosition == AVATAR_POSITION_END;
         // If in Rtl mode, the position should be flipped.
         return isRtl ? !assignedPosition : assignedPosition;
@@ -916,23 +900,18 @@
         mWorkPaint.setStyle(Style.STROKE);
         mWorkPaint.setStrokeWidth(borderWidth);
         mWorkPaint.setAntiAlias(true);
-        canvas.drawCircle(dst.centerX(), dst.centerY(), dst.width() / 2f - borderWidth / 2, mWorkPaint);
+        canvas.drawCircle(dst.centerX(), dst.centerY(), dst.width() / 2f - borderWidth / 2,
+                mWorkPaint);
 
         mWorkPaint.reset();
     }
 
-    private DrawableRecipientChip constructChipSpan(RecipientEntry contact, boolean pressed) {
+    private DrawableRecipientChip constructChipSpan(RecipientEntry contact) {
         TextPaint paint = getPaint();
         float defaultSize = paint.getTextSize();
         int defaultColor = paint.getColor();
 
-        Bitmap tmpBitmap;
-        if (pressed) {
-            tmpBitmap = createSelectedChip(contact, paint);
-
-        } else {
-            tmpBitmap = createUnselectedChip(contact, paint);
-        }
+        Bitmap tmpBitmap = createChipBitmap(contact, paint);
 
         // Pass the full text, un-ellipsized, to the chip.
         Drawable result = new BitmapDrawable(getResources(), tmpBitmap);
@@ -984,8 +963,6 @@
         Resources r = getContext().getResources();
 
         mChipBackground = a.getDrawable(R.styleable.RecipientEditTextView_chipBackground);
-        mChipBackgroundPressed = a
-                .getDrawable(R.styleable.RecipientEditTextView_chipBackgroundPressed);
         mInvalidChipBackground = a
                 .getDrawable(R.styleable.RecipientEditTextView_invalidChipBackground);
         mChipDelete = a.getDrawable(R.styleable.RecipientEditTextView_chipDelete);
@@ -1250,8 +1227,7 @@
             DrawableRecipientChip chip = null;
             try {
                 if (!mNoChips) {
-                    chip = visible ?
-                            constructChipSpan(entry, false) : new InvisibleRecipientChip(entry);
+                    chip = visible ? constructChipSpan(entry) : new InvisibleRecipientChip(entry);
                 }
             } catch (NullPointerException e) {
                 Log.e(TAG, e.getMessage(), e);
@@ -1289,12 +1265,11 @@
             return RecipientEntry.constructFakePhoneEntry(token, true);
         }
         Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(token);
-        String display = null;
         boolean isValid = isValid(token);
         if (isValid && tokens != null && tokens.length > 0) {
             // If we can get a name from tokenizing, then generate an entry from
             // this.
-            display = tokens[0].getName();
+            String display = tokens[0].getName();
             if (!TextUtils.isEmpty(display)) {
                 return RecipientEntry.constructGeneratedEntry(display, tokens[0].getAddress(),
                         isValid);
@@ -1375,7 +1350,7 @@
      * Dismiss any selected chips when the back key is pressed.
      */
     @Override
-    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
+    public boolean onKeyPreIme(int keyCode, @NonNull KeyEvent event) {
         if (keyCode == KeyEvent.KEYCODE_BACK && mSelectedChip != null) {
             clearSelectedChip();
             return true;
@@ -1392,7 +1367,7 @@
      * a commit key, then create a chip from the text they have entered.
      */
     @Override
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
+    public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) {
         switch (keyCode) {
             case KeyEvent.KEYCODE_TAB:
                 if (event.hasNoModifiers()) {
@@ -1488,11 +1463,11 @@
             }
             String text = editable.toString().substring(start, tokenEnd).trim();
             clearComposingText();
-            if (text != null && text.length() > 0 && !text.equals(" ")) {
+            if (text.length() > 0 && !text.equals(" ")) {
                 RecipientEntry entry = createTokenizedEntry(text);
                 if (entry != null) {
                     QwertyKeyListener.markAsReplaced(editable, start, end, "");
-                    CharSequence chipText = createChip(entry, false);
+                    CharSequence chipText = createChip(entry);
                     if (chipText != null && start > -1 && end > -1) {
                         editable.replace(start, end, chipText);
                     }
@@ -1554,10 +1529,7 @@
         }
         DrawableRecipientChip[] chips =
                 getSpannable().getSpans(start, end, DrawableRecipientChip.class);
-        if ((chips == null || chips.length == 0)) {
-            return false;
-        }
-        return true;
+        return chips != null && chips.length > 0;
     }
 
     private void handleEdit(int start, int end) {
@@ -1574,7 +1546,7 @@
         if (!TextUtils.isEmpty(text)) {
             RecipientEntry entry = RecipientEntry.constructFakeEntry(text, isValid(text));
             QwertyKeyListener.markAsReplaced(editable, start, end, "");
-            CharSequence chipText = createChip(entry, false);
+            CharSequence chipText = createChip(entry);
             int selEnd = getSelectionEnd();
             if (chipText != null && start > -1 && selEnd > -1) {
                 editable.replace(start, selEnd, chipText);
@@ -1588,7 +1560,7 @@
      * to the selected chip.
      */
     @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
+    public boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
         if (mSelectedChip != null && keyCode == KeyEvent.KEYCODE_DEL) {
             if (mAlternatesPopup != null && mAlternatesPopup.isShowing()) {
                 mAlternatesPopup.dismiss();
@@ -1637,7 +1609,7 @@
      * and makes sure that the range is not already a Chip.
      */
     @Override
-    protected void performFiltering(CharSequence text, int keyCode) {
+    protected void performFiltering(@NonNull CharSequence text, int keyCode) {
         boolean isCompletedToken = isCompletedToken(text);
         if (enoughToFilter() && !isCompletedToken) {
             int end = getSelectionEnd();
@@ -1683,6 +1655,7 @@
             mSelectedChip = null;
         }
         setCursorVisible(true);
+        setSelection(getText().length());
     }
 
     /**
@@ -1694,7 +1667,7 @@
      * If it isn't, then select that chip.
      */
     @Override
-    public boolean onTouchEvent(MotionEvent event) {
+    public boolean onTouchEvent(@NonNull MotionEvent event) {
         if (!isFocused()) {
             // Ignore any chip taps until this view is focused.
             return super.onTouchEvent(event);
@@ -1711,17 +1684,14 @@
             int offset = putOffsetInRange(x, y);
             DrawableRecipientChip currentChip = findChip(offset);
             if (currentChip != null) {
-                if (action == MotionEvent.ACTION_UP) {
-                    if (mSelectedChip != null && mSelectedChip != currentChip) {
-                        clearSelectedChip();
-                        mSelectedChip = selectChip(currentChip);
-                    } else if (mSelectedChip == null) {
-                        setSelection(getText().length());
-                        commitDefault();
-                        mSelectedChip = selectChip(currentChip);
-                    } else {
-                        onClick(mSelectedChip);
-                    }
+                if (mSelectedChip != null && mSelectedChip != currentChip) {
+                    clearSelectedChip();
+                    selectChip(currentChip);
+                } else if (mSelectedChip == null) {
+                    commitDefault();
+                    selectChip(currentChip);
+                } else {
+                    onClick(mSelectedChip);
                 }
                 chipWasSelected = true;
                 handled = true;
@@ -1735,12 +1705,6 @@
         return handled;
     }
 
-    private void scrollLineIntoView(int line) {
-        if (mScrollView != null) {
-            mScrollView.smoothScrollBy(0, calculateOffsetFromBottom(line));
-        }
-    }
-
     private void showAlternates(final DrawableRecipientChip currentChip,
             final ListPopupWindow alternatesPopup) {
         new AsyncTask<Void, Void, ListAdapter>() {
@@ -1862,11 +1826,11 @@
     }
 
     private DrawableRecipientChip findChip(int offset) {
-        DrawableRecipientChip[] chips =
-                getSpannable().getSpans(0, getText().length(), DrawableRecipientChip.class);
+        final Spannable span = getSpannable();
+        final DrawableRecipientChip[] chips =
+                span.getSpans(0, span.length(), DrawableRecipientChip.class);
         // Find the chip that contains this offset.
-        for (int i = 0; i < chips.length; i++) {
-            DrawableRecipientChip chip = chips[i];
+        for (DrawableRecipientChip chip : chips) {
             int start = getChipStart(chip);
             int end = getChipEnd(chip);
             if (offset >= start && offset <= end) {
@@ -1922,7 +1886,7 @@
         }
     }
 
-    private CharSequence createChip(RecipientEntry entry, boolean pressed) {
+    private CharSequence createChip(RecipientEntry entry) {
         final String displayText = createAddressText(entry);
         if (TextUtils.isEmpty(displayText)) {
             return null;
@@ -1932,7 +1896,7 @@
         final SpannableString  chipText = new SpannableString(displayText);
         if (!mNoChips) {
             try {
-                DrawableRecipientChip chip = constructChipSpan(entry, pressed);
+                DrawableRecipientChip chip = constructChipSpan(entry);
                 chipText.setSpan(chip, 0, textLength,
                         Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                 chip.setOriginalText(chipText.toString());
@@ -1980,7 +1944,7 @@
 
         Editable editable = getText();
         QwertyKeyListener.markAsReplaced(editable, start, end, "");
-        CharSequence chip = createChip(entry, false);
+        CharSequence chip = createChip(entry);
         if (chip != null && start >= 0 && end >= 0) {
             editable.replace(start, end, chip);
         }
@@ -2099,7 +2063,6 @@
             start = end; // move to the next token and get its end.
         }
         // Now, count total addresses.
-        start = 0;
         int tokenCount = countTokens(text);
         MoreImageSpan moreSpan = createMoreSpan(tokenCount - CHIP_LIMIT);
         SpannableString chipText = new SpannableString(text.subSequence(end, text.length()));
@@ -2235,14 +2198,11 @@
      * selecting the chip will take the contents of the chip and place it at
      * the end of the RecipientEditTextView for inline editing. If the
      * RecipientChip is a complete contact, then selecting the chip
-     * will change the background color of the chip, show the delete icon,
-     * and a popup window with the address in use highlighted and any other
+     * will show a popup window with the address in use highlighted and any other
      * alternate addresses for the contact.
      * @param currentChip Chip to select.
-     * @return A RecipientChip in the selected state or null if the chip
-     * just contained an email address.
      */
-    private DrawableRecipientChip selectChip(DrawableRecipientChip currentChip) {
+    private void selectChip(DrawableRecipientChip currentChip) {
         if (shouldShowEditableText(currentChip)) {
             CharSequence text = currentChip.getValue();
             Editable editable = getText();
@@ -2258,44 +2218,24 @@
             setCursorVisible(true);
             setSelection(editable.length());
             editable.append(text);
-            return constructChipSpan(
-                    RecipientEntry.constructFakeEntry((String) text, isValid(text.toString())),
-                    true);
+            mSelectedChip = constructChipSpan(
+                    RecipientEntry.constructFakeEntry((String) text, isValid(text.toString())));
         } else {
-            int start = getChipStart(currentChip);
-            int end = getChipEnd(currentChip);
-            getSpannable().removeSpan(currentChip);
-            DrawableRecipientChip newChip;
             final boolean showAddress =
                     currentChip.getContactId() == RecipientEntry.GENERATED_CONTACT ||
                     getAdapter().forceShowAddress();
-            try {
-                if (showAddress && mNoChips) {
-                    return null;
-                }
-                newChip = constructChipSpan(currentChip.getEntry(), true);
-            } catch (NullPointerException e) {
-                Log.e(TAG, e.getMessage(), e);
-                return null;
+            if (showAddress && mNoChips) {
+                return;
             }
-            Editable editable = getText();
-            QwertyKeyListener.markAsReplaced(editable, start, end, "");
-            if (start == -1 || end == -1) {
-                Log.d(TAG, "The chip being selected no longer exists but should.");
-            } else {
-                editable.setSpan(newChip, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-            }
-            newChip.setSelected(true);
-            if (shouldShowEditableText(newChip)) {
-                scrollLineIntoView(getLayout().getLineForOffset(getChipStart(newChip)));
-            }
-            if (showAddress) {
-                showAddress(newChip, mAddressPopup);
-            } else {
-                showAlternates(newChip, mAlternatesPopup);
-            }
+            mSelectedChip = currentChip;
+            setSelection(getText().getSpanEnd(mSelectedChip));
             setCursorVisible(false);
-            return newChip;
+
+            if (showAddress) {
+                showAddress(currentChip, mAddressPopup);
+            } else {
+                showAlternates(currentChip, mAlternatesPopup);
+            }
         }
     }
 
@@ -2348,7 +2288,7 @@
             editable.removeSpan(chip);
             try {
                 if (!mNoChips) {
-                    editable.setSpan(constructChipSpan(chip.getEntry(), false),
+                    editable.setSpan(constructChipSpan(chip.getEntry()),
                             start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                 }
             } catch (NullPointerException e) {
@@ -2375,6 +2315,7 @@
         if (mAddressPopup != null && mAddressPopup.isShowing()) {
             mAddressPopup.dismiss();
         }
+        setSelection(getText().length());
     }
 
     /**
@@ -2419,7 +2360,7 @@
         int end = getChipEnd(chip);
         getSpannable().removeSpan(chip);
         Editable editable = getText();
-        CharSequence chipText = createChip(entry, false);
+        CharSequence chipText = createChip(entry);
         if (chipText != null) {
             if (start == -1 || end == -1) {
                 Log.e(TAG, "The chip to replace does not exist but should.");
@@ -2549,16 +2490,16 @@
                         DrawableRecipientChip.class);
                 if (repl.length > 0) {
                     // There is a chip there! Just remove it.
+                    DrawableRecipientChip toDelete = repl[0];
                     Editable editable = getText();
                     // Add the separator token.
-                    int tokenStart = mTokenizer.findTokenStart(editable, selStart);
-                    int tokenEnd = mTokenizer.findTokenEnd(editable, tokenStart);
-                    tokenEnd = tokenEnd + 1;
-                    if (tokenEnd > editable.length()) {
-                        tokenEnd = editable.length();
+                    int deleteStart = editable.getSpanStart(toDelete);
+                    int deleteEnd = editable.getSpanEnd(toDelete) + 1;
+                    if (deleteEnd > editable.length()) {
+                        deleteEnd = editable.length();
                     }
-                    editable.delete(tokenStart, tokenEnd);
-                    getSpannable().removeSpan(repl[0]);
+                    editable.removeSpan(toDelete);
+                    editable.delete(deleteStart, deleteEnd);
                 }
             } else if (count > before) {
                 if (mSelectedChip != null
@@ -2738,7 +2679,7 @@
                 if (mNoChips) {
                     return null;
                 }
-                return constructChipSpan(entry, false);
+                return constructChipSpan(entry);
             } catch (NullPointerException e) {
                 Log.e(TAG, e.getMessage(), e);
                 return null;
@@ -2752,9 +2693,7 @@
             final List<DrawableRecipientChip> originalRecipients =
                     new ArrayList<DrawableRecipientChip>();
             final DrawableRecipientChip[] existingChips = getSortedRecipients();
-            for (int i = 0; i < existingChips.length; i++) {
-                originalRecipients.add(existingChips[i]);
-            }
+            Collections.addAll(originalRecipients, existingChips);
             if (mRemovedSpans != null) {
                 originalRecipients.addAll(mRemovedSpans);
             }
@@ -2785,16 +2724,12 @@
             final ArrayList<DrawableRecipientChip> recipients =
                     new ArrayList<DrawableRecipientChip>();
             DrawableRecipientChip[] existingChips = getSortedRecipients();
-            for (int i = 0; i < existingChips.length; i++) {
-                recipients.add(existingChips[i]);
-            }
+            Collections.addAll(recipients, existingChips);
             if (mRemovedSpans != null) {
                 recipients.addAll(mRemovedSpans);
             }
             ArrayList<String> addresses = new ArrayList<String>();
-            DrawableRecipientChip chip;
-            for (int i = 0; i < recipients.size(); i++) {
-                chip = recipients.get(i);
+            for (DrawableRecipientChip chip : recipients) {
                 if (chip != null) {
                     addresses.add(createAddressText(chip.getEntry()));
                 }
@@ -2919,9 +2854,7 @@
             // chip.
             final ArrayList<DrawableRecipientChip> originalRecipients = params[0];
             ArrayList<String> addresses = new ArrayList<String>();
-            DrawableRecipientChip chip;
-            for (int i = 0; i < originalRecipients.size(); i++) {
-                chip = originalRecipients.get(i);
+            for (DrawableRecipientChip chip : originalRecipients) {
                 if (chip != null) {
                     addresses.add(createAddressText(chip.getEntry()));
                 }
@@ -3009,8 +2942,7 @@
     private int supportGetOffsetForPosition(float x, float y) {
         if (getLayout() == null) return -1;
         final int line = supportGetLineAtCoordinate(y);
-        final int offset = supportGetOffsetAtCoordinate(line, x);
-        return offset;
+        return supportGetOffsetAtCoordinate(line, x);
     }
 
     private float supportConvertToLocalHorizontalCoordinate(float x) {
@@ -3063,7 +2995,7 @@
      * Handles drag event.
      */
     @Override
-    public boolean onDragEvent(DragEvent event) {
+    public boolean onDragEvent(@NonNull DragEvent event) {
         switch (event.getAction()) {
             case DragEvent.ACTION_DRAG_STARTED:
                 // Only handle plain text drag and drop.
@@ -3089,14 +3021,15 @@
         }
 
         @Override
-        public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
+        public void onProvideShadowMetrics(@NonNull Point shadowSize,
+                @NonNull Point shadowTouchPoint) {
             Rect rect = mChip.getBounds();
             shadowSize.set(rect.width(), rect.height());
             shadowTouchPoint.set(rect.centerX(), rect.centerY());
         }
 
         @Override
-        public void onDrawShadow(Canvas canvas) {
+        public void onDrawShadow(@NonNull Canvas canvas) {
             mChip.draw(canvas);
         }
     }
@@ -3184,7 +3117,7 @@
             chipInsertionPoint = editable.getSpanEnd(last) + 1;
         }
 
-        final CharSequence chip = createChip(entry, false);
+        final CharSequence chip = createChip(entry);
         if (chip != null) {
             editable.insert(chipInsertionPoint, chip);
         }