Loading core/java/android/widget/Editor.java +13 −1 Original line number Diff line number Diff line Loading @@ -107,6 +107,7 @@ import android.widget.AdapterView.OnItemClickListener; import android.widget.TextView.Drawables; import android.widget.TextView.OnEditorActionListener; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.GrowingArrayUtils; import com.android.internal.util.Preconditions; Loading Loading @@ -2632,7 +2633,8 @@ public class Editor { } } private class SuggestionsPopupWindow extends PinnedPopupWindow implements OnItemClickListener { @VisibleForTesting public class SuggestionsPopupWindow extends PinnedPopupWindow implements OnItemClickListener { private static final int MAX_NUMBER_SUGGESTIONS = SuggestionSpan.SUGGESTIONS_MAX_SIZE; private static final int ADD_TO_DICTIONARY = -1; private static final int DELETE_TEXT = -2; Loading Loading @@ -2798,6 +2800,11 @@ public class Editor { return suggestionSpans; } @VisibleForTesting public ViewGroup getContentViewForTesting() { return mContentView; } @Override public void show() { if (!(mTextView.getText() instanceof Editable)) return; Loading Loading @@ -5103,6 +5110,11 @@ public class Editor { return 0 <= start && start <= end && end <= text.length(); } @VisibleForTesting public SuggestionsPopupWindow getSuggestionsPopupWindowForTesting() { return mSuggestionsPopupWindow; } /** * An InputFilter that monitors text input to maintain undo history. It does not modify the * text being typed (and hence always returns null from the filter() method). Loading core/java/android/widget/TextView.java +10 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,7 @@ import android.view.textservice.SpellCheckerSubtype; import android.view.textservice.TextServicesManager; import android.widget.RemoteViews.RemoteView; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.FastMath; import com.android.internal.widget.EditableInputConnection; Loading Loading @@ -1695,6 +1696,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener throw new UnsupportedOperationException("not implemented"); } /** * @hide */ @VisibleForTesting public final Editor getEditorForTesting() { return mEditor; } /** * Associate an {@link android.content.UndoManager} with this TextView. Once * done, all edit operations on the TextView will result in appropriate Loading core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java 0 → 100644 +117 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.widget; import android.app.Activity; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.SmallTest; import android.text.Selection; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextPaint; import android.text.style.SuggestionSpan; import android.text.style.TextAppearanceSpan; import com.android.frameworks.coretests.R; /** * SuggestionsPopupWindowTest tests. */ public class SuggestionsPopupWindowTest extends ActivityInstrumentationTestCase2<TextViewActivity> { public SuggestionsPopupWindowTest() { super(TextViewActivity.class); } @SmallTest public void testTextAndAppearanceInSuggestionsPopup() { final Activity activity = getActivity(); final String sampleText = "abc def ghi"; final String[] candidate = {"DEF", "Def"}; final SuggestionSpan suggestionSpan = new SuggestionSpan(activity, candidate, SuggestionSpan.FLAG_AUTO_CORRECTION); final int spanStart = 4; final int spanEnd = 7; TextAppearanceSpan expectedSpan = new TextAppearanceSpan(activity, android.R.style.TextAppearance_SuggestionHighlight); TextPaint tmpTp = new TextPaint(); expectedSpan.updateDrawState(tmpTp); final int expectedHighlightTextColor = tmpTp.getColor(); final float expectedHighlightTextSize = tmpTp.getTextSize(); // Create and wait until SuggestionsPopupWindow is shown. final EditText editText = (EditText) activity.findViewById(R.id.textview); final Editor editor = editText.getEditorForTesting(); assertNotNull(editor); activity.runOnUiThread(new Runnable() { public void run() { SpannableStringBuilder ssb = new SpannableStringBuilder(); ssb.append(sampleText); ssb.setSpan(suggestionSpan, spanStart, spanEnd, Spanned.SPAN_INCLUSIVE_INCLUSIVE); editText.setText(ssb); Selection.setSelection(editText.getText(), spanStart, spanEnd); editText.onTextContextMenuItem(TextView.ID_REPLACE); } }); getInstrumentation().waitForIdleSync(); // In this test, the SuggestionsPopupWindow looks like // abc def ghi // ---------- // | *DEF* | // | *Def* | // | DELETE | // ---------- // *XX* means that XX is highlighted. activity.runOnUiThread(new Runnable() { public void run() { Editor.SuggestionsPopupWindow popupWindow = editor.getSuggestionsPopupWindowForTesting(); assertNotNull(popupWindow); ListView listView = (ListView) popupWindow.getContentViewForTesting(); assertNotNull(listView); int childNum = listView.getChildCount(); // +1 for "DELETE" command. assertEquals(candidate.length + 1, childNum); for (int i = 0; i < candidate.length; ++i) { TextView textView = (TextView) listView.getChildAt(i); assertNotNull(textView); Spanned spanned = (Spanned) textView.getText(); assertNotNull(spanned); // Check that the suggestion item order is kept. assertEquals(candidate[i], spanned.toString()); // Check that the text is highlighted with correct color and text size. TextAppearanceSpan[] taSpan = spanned.getSpans(0, candidate[i].length(), TextAppearanceSpan.class); assertEquals(1, taSpan.length); TextPaint tp = new TextPaint(); taSpan[0].updateDrawState(tp); assertEquals(expectedHighlightTextColor, tp.getColor()); assertEquals(expectedHighlightTextSize, tp.getTextSize()); } } }); } } Loading
core/java/android/widget/Editor.java +13 −1 Original line number Diff line number Diff line Loading @@ -107,6 +107,7 @@ import android.widget.AdapterView.OnItemClickListener; import android.widget.TextView.Drawables; import android.widget.TextView.OnEditorActionListener; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.GrowingArrayUtils; import com.android.internal.util.Preconditions; Loading Loading @@ -2632,7 +2633,8 @@ public class Editor { } } private class SuggestionsPopupWindow extends PinnedPopupWindow implements OnItemClickListener { @VisibleForTesting public class SuggestionsPopupWindow extends PinnedPopupWindow implements OnItemClickListener { private static final int MAX_NUMBER_SUGGESTIONS = SuggestionSpan.SUGGESTIONS_MAX_SIZE; private static final int ADD_TO_DICTIONARY = -1; private static final int DELETE_TEXT = -2; Loading Loading @@ -2798,6 +2800,11 @@ public class Editor { return suggestionSpans; } @VisibleForTesting public ViewGroup getContentViewForTesting() { return mContentView; } @Override public void show() { if (!(mTextView.getText() instanceof Editable)) return; Loading Loading @@ -5103,6 +5110,11 @@ public class Editor { return 0 <= start && start <= end && end <= text.length(); } @VisibleForTesting public SuggestionsPopupWindow getSuggestionsPopupWindowForTesting() { return mSuggestionsPopupWindow; } /** * An InputFilter that monitors text input to maintain undo history. It does not modify the * text being typed (and hence always returns null from the filter() method). Loading
core/java/android/widget/TextView.java +10 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,7 @@ import android.view.textservice.SpellCheckerSubtype; import android.view.textservice.TextServicesManager; import android.widget.RemoteViews.RemoteView; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.FastMath; import com.android.internal.widget.EditableInputConnection; Loading Loading @@ -1695,6 +1696,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener throw new UnsupportedOperationException("not implemented"); } /** * @hide */ @VisibleForTesting public final Editor getEditorForTesting() { return mEditor; } /** * Associate an {@link android.content.UndoManager} with this TextView. Once * done, all edit operations on the TextView will result in appropriate Loading
core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java 0 → 100644 +117 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.widget; import android.app.Activity; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.SmallTest; import android.text.Selection; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextPaint; import android.text.style.SuggestionSpan; import android.text.style.TextAppearanceSpan; import com.android.frameworks.coretests.R; /** * SuggestionsPopupWindowTest tests. */ public class SuggestionsPopupWindowTest extends ActivityInstrumentationTestCase2<TextViewActivity> { public SuggestionsPopupWindowTest() { super(TextViewActivity.class); } @SmallTest public void testTextAndAppearanceInSuggestionsPopup() { final Activity activity = getActivity(); final String sampleText = "abc def ghi"; final String[] candidate = {"DEF", "Def"}; final SuggestionSpan suggestionSpan = new SuggestionSpan(activity, candidate, SuggestionSpan.FLAG_AUTO_CORRECTION); final int spanStart = 4; final int spanEnd = 7; TextAppearanceSpan expectedSpan = new TextAppearanceSpan(activity, android.R.style.TextAppearance_SuggestionHighlight); TextPaint tmpTp = new TextPaint(); expectedSpan.updateDrawState(tmpTp); final int expectedHighlightTextColor = tmpTp.getColor(); final float expectedHighlightTextSize = tmpTp.getTextSize(); // Create and wait until SuggestionsPopupWindow is shown. final EditText editText = (EditText) activity.findViewById(R.id.textview); final Editor editor = editText.getEditorForTesting(); assertNotNull(editor); activity.runOnUiThread(new Runnable() { public void run() { SpannableStringBuilder ssb = new SpannableStringBuilder(); ssb.append(sampleText); ssb.setSpan(suggestionSpan, spanStart, spanEnd, Spanned.SPAN_INCLUSIVE_INCLUSIVE); editText.setText(ssb); Selection.setSelection(editText.getText(), spanStart, spanEnd); editText.onTextContextMenuItem(TextView.ID_REPLACE); } }); getInstrumentation().waitForIdleSync(); // In this test, the SuggestionsPopupWindow looks like // abc def ghi // ---------- // | *DEF* | // | *Def* | // | DELETE | // ---------- // *XX* means that XX is highlighted. activity.runOnUiThread(new Runnable() { public void run() { Editor.SuggestionsPopupWindow popupWindow = editor.getSuggestionsPopupWindowForTesting(); assertNotNull(popupWindow); ListView listView = (ListView) popupWindow.getContentViewForTesting(); assertNotNull(listView); int childNum = listView.getChildCount(); // +1 for "DELETE" command. assertEquals(candidate.length + 1, childNum); for (int i = 0; i < candidate.length; ++i) { TextView textView = (TextView) listView.getChildAt(i); assertNotNull(textView); Spanned spanned = (Spanned) textView.getText(); assertNotNull(spanned); // Check that the suggestion item order is kept. assertEquals(candidate[i], spanned.toString()); // Check that the text is highlighted with correct color and text size. TextAppearanceSpan[] taSpan = spanned.getSpans(0, candidate[i].length(), TextAppearanceSpan.class); assertEquals(1, taSpan.length); TextPaint tp = new TextPaint(); taSpan[0].updateDrawState(tp); assertEquals(expectedHighlightTextColor, tp.getColor()); assertEquals(expectedHighlightTextSize, tp.getTextSize()); } } }); } }