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

Commit 76b51dc4 authored by Abodunrinwa Toki's avatar Abodunrinwa Toki
Browse files

Disable smart sharing for password fields.

Test: bit FrameworksCoreTests:android.widget.TextViewActivityTest
bit CtsWidgetTestCases:android.widget.cts.TextViewTest
Bug: 62340817
Change-Id: Ifbf2c39d9f304251adc8c4acdf1b4fd6914011d8
parent a8519d2f
Loading
Loading
Loading
Loading
+11 −12
Original line number Diff line number Diff line
@@ -68,9 +68,7 @@ final class SelectionActionModeHelper {

    public void startActionModeAsync(boolean adjustSelection) {
        cancelAsyncTask();
        if (isNoOpTextClassifier() || !hasSelection()) {
            // No need to make an async call for a no-op TextClassifier.
            // Do not call the TextClassifier if there is no selection.
        if (skipTextClassification()) {
            startActionMode(null);
        } else {
            resetTextClassificationHelper(true /* resetSelectionTag */);
@@ -88,9 +86,7 @@ final class SelectionActionModeHelper {

    public void invalidateActionModeAsync() {
        cancelAsyncTask();
        if (isNoOpTextClassifier() || !hasSelection()) {
            // No need to make an async call for a no-op TextClassifier.
            // Do not call the TextClassifier if there is no selection.
        if (skipTextClassification()) {
            invalidateActionMode(null);
        } else {
            resetTextClassificationHelper(false /* resetSelectionTag */);
@@ -132,13 +128,16 @@ final class SelectionActionModeHelper {
        mTextClassification = null;
    }

    private boolean isNoOpTextClassifier() {
        return mEditor.getTextView().getTextClassifier() == TextClassifier.NO_OP;
    }

    private boolean hasSelection() {
    private boolean skipTextClassification() {
        final TextView textView = mEditor.getTextView();
        return textView.getSelectionEnd() > textView.getSelectionStart();
        // No need to make an async call for a no-op TextClassifier.
        final boolean noOpTextClassifier = textView.getTextClassifier() == TextClassifier.NO_OP;
        // Do not call the TextClassifier if there is no selection.
        final boolean noSelection = textView.getSelectionEnd() == textView.getSelectionStart();
        // Do not call the TextClassifier if this is a password field.
        final boolean password = textView.hasPasswordTransformationMethod()
                || TextView.isPasswordInputType(textView.getInputType());
        return noOpTextClassifier || noSelection || password;
    }

    private void startActionMode(@Nullable SelectionResult result) {
+1 −1
Original line number Diff line number Diff line
@@ -5674,7 +5674,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        return mTransformation instanceof PasswordTransformationMethod;
    }

    private static boolean isPasswordInputType(int inputType) {
    static boolean isPasswordInputType(int inputType) {
        final int variation =
                inputType & (EditorInfo.TYPE_MASK_CLASS | EditorInfo.TYPE_MASK_VARIATION);
        return variation
+22 −1
Original line number Diff line number Diff line
@@ -786,7 +786,7 @@ public class TextViewActivityTest {

    @Test
    public void testAssistItemIsAtIndexZero() throws Throwable {
        mActivity.getSystemService(TextClassificationManager.class).setTextClassifier(null);
        useSystemDefaultTextClassifier();
        final TextView textView = mActivity.findViewById(R.id.textview);
        mActivityRule.runOnUiThread(() -> textView.setCustomSelectionActionModeCallback(
                new ActionMode.Callback() {
@@ -821,6 +821,23 @@ public class TextViewActivityTest {
        assertFloatingToolbarItemIndex(android.R.id.textAssist, 0);
    }

    @Test
    public void testNoAssistItemForPasswordField() throws Throwable {
        useSystemDefaultTextClassifier();
        final TextView textView = mActivity.findViewById(R.id.textview);
        mActivityRule.runOnUiThread(() -> {
            textView.setInputType(
                    InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
        });
        mInstrumentation.waitForIdleSync();
        final String password = "afigbo@android.com";

        onView(withId(R.id.textview)).perform(replaceText(password));
        onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(password.indexOf('@')));
        sleepForFloatingToolbarPopup();
        assertFloatingToolbarDoesNotContainItem(android.R.id.textAssist);
    }

    @Test
    public void testPastePlainText_menuAction() {
        initializeClipboardWithText(TextStyle.STYLED);
@@ -848,6 +865,10 @@ public class TextViewActivityTest {
                mActivity.getString(com.android.internal.R.string.paste_as_plain_text));
    }

    private void useSystemDefaultTextClassifier() {
        mActivity.getSystemService(TextClassificationManager.class).setTextClassifier(null);
    }

    private void initializeClipboardWithText(TextStyle textStyle) {
        final ClipData clip;
        switch (textStyle) {
+44 −9
Original line number Diff line number Diff line
@@ -23,29 +23,31 @@ import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.isRoot;
import static android.support.test.espresso.matcher.ViewMatchers.withTagValue;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withTagValue;
import static android.support.test.espresso.matcher.ViewMatchers.withText;

import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;

import android.view.MenuItem;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;

import android.support.test.espresso.NoMatchingRootException;
import android.support.test.espresso.NoMatchingViewException;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.ViewInteraction;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import com.android.internal.widget.FloatingToolbar;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;

import java.util.ArrayList;
import java.util.List;

/**
 * Espresso utility methods for the floating toolbar.
 */
@@ -176,6 +178,39 @@ public class FloatingToolbarEspressoUtils {
        throw new AssertionError("Floating toolbar contains " + itemLabel);
    }

    /**
     * Asserts that the floating toolbar does not contain a menu item with the specified id.
     *
     * @param menuItemId id of the menu item
     * @throws AssertionError if the assertion fails
     */
    public static void assertFloatingToolbarDoesNotContainItem(final int menuItemId) {
        onFloatingToolBar().check(matches(new TypeSafeMatcher<View>() {
            @Override
            public boolean matchesSafely(View view) {
                return !hasMenuItemWithSpecifiedId(view);
            }

            @Override
            public void describeTo(Description description) {}

            private boolean hasMenuItemWithSpecifiedId(View view) {
                if (view.getTag() instanceof MenuItem
                        && ((MenuItem) view.getTag()).getItemId() == menuItemId) {
                    return true;
                } else if (view instanceof ViewGroup) {
                    ViewGroup viewGroup = (ViewGroup) view;
                    for (int i = 0; i < viewGroup.getChildCount(); i++) {
                        if (hasMenuItemWithSpecifiedId(viewGroup.getChildAt(i))) {
                            return true;
                        }
                    }
                }
                return false;
            }
        }));
    }

    /**
     * Click specified item on the floating tool bar.
     *