Loading core/java/android/widget/Editor.java +2 −8 Original line number Diff line number Diff line Loading @@ -2095,14 +2095,7 @@ public class Editor { if (!(mTextView.getText() instanceof Spannable)) { return; } Spannable text = (Spannable) mTextView.getText(); stopTextActionMode(); if (mTextView.isTextSelectable()) { Selection.setSelection((Spannable) text, link.getStart(), link.getEnd()); } else { //TODO: Nonselectable text } getSelectionActionModeHelper().startLinkActionModeAsync(link); } Loading Loading @@ -2179,7 +2172,8 @@ public class Editor { return false; } if (!checkField() || !mTextView.hasSelection()) { if (actionMode != TextActionMode.TEXT_LINK && (!checkField() || !mTextView.hasSelection())) { return false; } Loading core/java/android/widget/SelectionActionModeHelper.java +29 −5 Original line number Diff line number Diff line Loading @@ -235,10 +235,13 @@ public final class SelectionActionModeHelper { @Editor.TextActionMode int actionMode, @Nullable SelectionResult result) { final CharSequence text = getText(mTextView); if (result != null && text instanceof Spannable && (mTextView.isTextSelectable() || mTextView.isTextEditable())) { && (mTextView.isTextSelectable() || mTextView.isTextEditable() || actionMode == Editor.TextActionMode.TEXT_LINK)) { // Do not change the selection if TextClassifier should be dark launched. if (!mTextView.getTextClassifier().getSettings().isDarkLaunch()) { Selection.setSelection((Spannable) text, result.mStart, result.mEnd); mTextView.invalidate(); } mTextClassification = result.mClassification; } else { Loading @@ -250,8 +253,17 @@ public final class SelectionActionModeHelper { && (mTextView.isTextSelectable() || mTextView.isTextEditable())) { controller.show(); } if (result != null && actionMode == Editor.TextActionMode.SELECTION) { if (result != null) { switch (actionMode) { case Editor.TextActionMode.SELECTION: mSelectionTracker.onSmartSelection(result); break; case Editor.TextActionMode.TEXT_LINK: mSelectionTracker.onLinkSelected(result); break; default: break; } } } mEditor.setRestartActionModeOnNextRefresh(false); Loading Loading @@ -486,12 +498,24 @@ public final class SelectionActionModeHelper { * Called when selection action mode is started and the results come from a classifier. */ public void onSmartSelection(SelectionResult result) { onClassifiedSelection(result); mLogger.logSelectionModified( result.mStart, result.mEnd, result.mClassification, result.mSelection); } /** * Called when link action mode is started and the classification comes from a classifier. */ public void onLinkSelected(SelectionResult result) { onClassifiedSelection(result); // TODO: log (b/70246800) } private void onClassifiedSelection(SelectionResult result) { if (isSelectionStarted()) { mSelectionStart = result.mStart; mSelectionEnd = result.mEnd; mAllowReset = mSelectionStart != mOriginalStart || mSelectionEnd != mOriginalEnd; mLogger.logSelectionModified( result.mStart, result.mEnd, result.mClassification, result.mSelection); } } Loading core/java/android/widget/TextView.java +3 −5 Original line number Diff line number Diff line Loading @@ -11233,12 +11233,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ public boolean requestActionMode(@NonNull TextLinks.TextLink link) { Preconditions.checkNotNull(link); if (mEditor != null) { createEditorIfNeeded(); mEditor.startLinkActionModeAsync(link); return true; } return false; } /** * @hide */ Loading core/tests/coretests/res/layout/activity_text_view.xml +5 −0 Original line number Diff line number Diff line Loading @@ -25,4 +25,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/nonselectable_textview" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> core/tests/coretests/src/android/widget/TextViewActivityTest.java +11 −2 Original line number Diff line number Diff line Loading @@ -311,11 +311,20 @@ public class TextViewActivityTest { @Test public void testToolbarAppearsAfterLinkClicked() throws Throwable { runToolbarAppearsAfterLinkClickedTest(R.id.textview); } @Test public void testToolbarAppearsAfterLinkClickedNonselectable() throws Throwable { runToolbarAppearsAfterLinkClickedTest(R.id.nonselectable_textview); } private void runToolbarAppearsAfterLinkClickedTest(int id) throws Throwable { TextView textView = mActivity.findViewById(id); useSystemDefaultTextClassifier(); TextClassificationManager textClassificationManager = mActivity.getSystemService(TextClassificationManager.class); TextClassifier textClassifier = textClassificationManager.getTextClassifier(); final TextView textView = mActivity.findViewById(R.id.textview); SpannableString content = new SpannableString("Call me at +19148277737"); TextLinks links = textClassifier.generateLinks(content); links.apply(content, null); Loading @@ -331,7 +340,7 @@ public class TextViewActivityTest { TextLinks.TextLink textLink = links.getLinks().iterator().next(); int position = (textLink.getStart() + textLink.getEnd()) / 2; onView(withId(R.id.textview)).perform(clickOnTextAtIndex(position)); onView(withId(id)).perform(clickOnTextAtIndex(position)); sleepForFloatingToolbarPopup(); assertFloatingToolbarIsDisplayed(); } Loading Loading
core/java/android/widget/Editor.java +2 −8 Original line number Diff line number Diff line Loading @@ -2095,14 +2095,7 @@ public class Editor { if (!(mTextView.getText() instanceof Spannable)) { return; } Spannable text = (Spannable) mTextView.getText(); stopTextActionMode(); if (mTextView.isTextSelectable()) { Selection.setSelection((Spannable) text, link.getStart(), link.getEnd()); } else { //TODO: Nonselectable text } getSelectionActionModeHelper().startLinkActionModeAsync(link); } Loading Loading @@ -2179,7 +2172,8 @@ public class Editor { return false; } if (!checkField() || !mTextView.hasSelection()) { if (actionMode != TextActionMode.TEXT_LINK && (!checkField() || !mTextView.hasSelection())) { return false; } Loading
core/java/android/widget/SelectionActionModeHelper.java +29 −5 Original line number Diff line number Diff line Loading @@ -235,10 +235,13 @@ public final class SelectionActionModeHelper { @Editor.TextActionMode int actionMode, @Nullable SelectionResult result) { final CharSequence text = getText(mTextView); if (result != null && text instanceof Spannable && (mTextView.isTextSelectable() || mTextView.isTextEditable())) { && (mTextView.isTextSelectable() || mTextView.isTextEditable() || actionMode == Editor.TextActionMode.TEXT_LINK)) { // Do not change the selection if TextClassifier should be dark launched. if (!mTextView.getTextClassifier().getSettings().isDarkLaunch()) { Selection.setSelection((Spannable) text, result.mStart, result.mEnd); mTextView.invalidate(); } mTextClassification = result.mClassification; } else { Loading @@ -250,8 +253,17 @@ public final class SelectionActionModeHelper { && (mTextView.isTextSelectable() || mTextView.isTextEditable())) { controller.show(); } if (result != null && actionMode == Editor.TextActionMode.SELECTION) { if (result != null) { switch (actionMode) { case Editor.TextActionMode.SELECTION: mSelectionTracker.onSmartSelection(result); break; case Editor.TextActionMode.TEXT_LINK: mSelectionTracker.onLinkSelected(result); break; default: break; } } } mEditor.setRestartActionModeOnNextRefresh(false); Loading Loading @@ -486,12 +498,24 @@ public final class SelectionActionModeHelper { * Called when selection action mode is started and the results come from a classifier. */ public void onSmartSelection(SelectionResult result) { onClassifiedSelection(result); mLogger.logSelectionModified( result.mStart, result.mEnd, result.mClassification, result.mSelection); } /** * Called when link action mode is started and the classification comes from a classifier. */ public void onLinkSelected(SelectionResult result) { onClassifiedSelection(result); // TODO: log (b/70246800) } private void onClassifiedSelection(SelectionResult result) { if (isSelectionStarted()) { mSelectionStart = result.mStart; mSelectionEnd = result.mEnd; mAllowReset = mSelectionStart != mOriginalStart || mSelectionEnd != mOriginalEnd; mLogger.logSelectionModified( result.mStart, result.mEnd, result.mClassification, result.mSelection); } } Loading
core/java/android/widget/TextView.java +3 −5 Original line number Diff line number Diff line Loading @@ -11233,12 +11233,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ public boolean requestActionMode(@NonNull TextLinks.TextLink link) { Preconditions.checkNotNull(link); if (mEditor != null) { createEditorIfNeeded(); mEditor.startLinkActionModeAsync(link); return true; } return false; } /** * @hide */ Loading
core/tests/coretests/res/layout/activity_text_view.xml +5 −0 Original line number Diff line number Diff line Loading @@ -25,4 +25,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/nonselectable_textview" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
core/tests/coretests/src/android/widget/TextViewActivityTest.java +11 −2 Original line number Diff line number Diff line Loading @@ -311,11 +311,20 @@ public class TextViewActivityTest { @Test public void testToolbarAppearsAfterLinkClicked() throws Throwable { runToolbarAppearsAfterLinkClickedTest(R.id.textview); } @Test public void testToolbarAppearsAfterLinkClickedNonselectable() throws Throwable { runToolbarAppearsAfterLinkClickedTest(R.id.nonselectable_textview); } private void runToolbarAppearsAfterLinkClickedTest(int id) throws Throwable { TextView textView = mActivity.findViewById(id); useSystemDefaultTextClassifier(); TextClassificationManager textClassificationManager = mActivity.getSystemService(TextClassificationManager.class); TextClassifier textClassifier = textClassificationManager.getTextClassifier(); final TextView textView = mActivity.findViewById(R.id.textview); SpannableString content = new SpannableString("Call me at +19148277737"); TextLinks links = textClassifier.generateLinks(content); links.apply(content, null); Loading @@ -331,7 +340,7 @@ public class TextViewActivityTest { TextLinks.TextLink textLink = links.getLinks().iterator().next(); int position = (textLink.getStart() + textLink.getEnd()) / 2; onView(withId(R.id.textview)).perform(clickOnTextAtIndex(position)); onView(withId(id)).perform(clickOnTextAtIndex(position)); sleepForFloatingToolbarPopup(); assertFloatingToolbarIsDisplayed(); } Loading