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

Commit 3d10089d authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Hide hint text when starting handwriting" into udc-dev

parents b5b4eb70 4cf7ba63
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Rect;
import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;

import com.android.internal.annotations.VisibleForTesting;

@@ -305,6 +306,9 @@ public class HandwritingInitiator {
        mImm.startStylusHandwriting(view);
        mState.mHasInitiatedHandwriting = true;
        mState.mShouldInitHandwriting = false;
        if (view instanceof TextView) {
            ((TextView) view).hideHint();
        }
    }

    /**
@@ -323,6 +327,9 @@ public class HandwritingInitiator {
                mState.mHasInitiatedHandwriting = true;
                mState.mShouldInitHandwriting = false;
            }
            if (view instanceof TextView) {
                ((TextView) view).hideHint();
            }
            return true;
        }
        return false;
+22 −2
Original line number Diff line number Diff line
@@ -806,6 +806,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    private CharSequence mHint;
    @UnsupportedAppUsage
    private Layout mHintLayout;
    private boolean mHideHint;
    private MovementMethod mMovement;
@@ -7180,6 +7181,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        sendOnTextChanged(text, 0, oldlen, textLength);
        onTextChanged(text, 0, oldlen, textLength);
        mHideHint = false;
        if (a11yTextChangeType == AccessibilityUtils.TEXT) {
            notifyViewAccessibilityStateChangedIfNeeded(
                    AccessibilityEvent.CONTENT_CHANGE_TYPE_TEXT);
@@ -7338,6 +7341,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    }
    private void setHintInternal(CharSequence hint) {
        mHideHint = false;
        mHint = TextUtils.stringOrSpannedString(hint);
        if (mLayout != null) {
@@ -7378,6 +7382,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        return mHint;
    }
    /**
     * Temporarily hides the hint text until the text is modified, or the hint text is modified, or
     * the view gains or loses focus.
     *
     * @hide
     */
    public void hideHint() {
        if (isShowingHint()) {
            mHideHint = true;
            invalidate();
        }
    }
    /**
     * Returns if the text is constrained to a single horizontally scrolling line ignoring new
     * line characters instead of letting it wrap onto multiple lines.
@@ -8974,7 +8991,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        Layout layout = mLayout;
        if (mHint != null && mText.length() == 0) {
        if (mHint != null && !mHideHint && mText.length() == 0) {
            if (mHintTextColor != null) {
                color = mCurHintTextColor;
            }
@@ -11293,7 +11310,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    }
    private boolean isShowingHint() {
        return TextUtils.isEmpty(mText) && !TextUtils.isEmpty(mHint);
        return TextUtils.isEmpty(mText) && !TextUtils.isEmpty(mHint) && !mHideHint;
    }
    /**
@@ -12437,6 +12454,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        sendOnTextChanged(buffer, start, before, after);
        onTextChanged(buffer, start, before, after);
        mHideHint = false;
        clearGesturePreviewHighlight();
    }
@@ -12577,6 +12595,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            return;
        }
        mHideHint = false;
        if (mEditor != null) mEditor.onFocusChanged(focused, direction);
        if (focused) {
+114 −0
Original line number Diff line number Diff line
@@ -23,14 +23,20 @@ import static android.view.stylus.HandwritingTestUtil.createView;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.Instrumentation;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.view.HandwritingInitiator;
@@ -38,7 +44,9 @@ import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -47,6 +55,7 @@ import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;

/**
 * Tests for {@link HandwritingInitiator}
@@ -543,6 +552,111 @@ public class HandwritingInitiatorTest {
        assertThat(mHandwritingInitiator.mConnectedView.get()).isEqualTo(mTestView1);
    }

    @Test
    public void startHandwriting_hidesHint() {
        EditText editText =
                new EditText(InstrumentationRegistry.getInstrumentation().getTargetContext());
        editText.setHint("hint");
        editText.setLayoutParams(new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));

        verifyEditTextDrawsText(editText, "hint");

        mHandwritingInitiator.onTouchEvent(createStylusEvent(ACTION_DOWN, 0, 0, 0));
        mHandwritingInitiator.startHandwriting(editText);

        verifyEditTextDrawsText(editText, null);
    }

    @Test
    public void startHandwriting_clearFocus_restoresHint() {
        EditText editText =
                new EditText(InstrumentationRegistry.getInstrumentation().getTargetContext());
        editText.setHint("hint");
        editText.setLayoutParams(new ViewGroup.LayoutParams(1024, 1024));
        editText.requestFocus();

        verifyEditTextDrawsText(editText, "hint");

        mHandwritingInitiator.onTouchEvent(createStylusEvent(ACTION_DOWN, 0, 0, 0));
        mHandwritingInitiator.startHandwriting(editText);

        verifyEditTextDrawsText(editText, null);

        editText.clearFocus();

        verifyEditTextDrawsText(editText, "hint");
    }

    @Test
    public void startHandwriting_setHint_restoresHint() {
        EditText editText =
                new EditText(InstrumentationRegistry.getInstrumentation().getTargetContext());
        editText.setHint("hint");
        editText.setLayoutParams(new ViewGroup.LayoutParams(1024, 1024));

        verifyEditTextDrawsText(editText, "hint");

        mHandwritingInitiator.onTouchEvent(createStylusEvent(ACTION_DOWN, 0, 0, 0));
        mHandwritingInitiator.startHandwriting(editText);

        verifyEditTextDrawsText(editText, null);

        editText.setHint("new hint");

        verifyEditTextDrawsText(editText, "new hint");
    }

    @Test
    public void startHandwriting_setText_restoresHint() {
        EditText editText =
                new EditText(InstrumentationRegistry.getInstrumentation().getTargetContext());
        editText.setHint("hint");
        editText.setLayoutParams(new ViewGroup.LayoutParams(1024, 1024));

        verifyEditTextDrawsText(editText, "hint");

        mHandwritingInitiator.onTouchEvent(createStylusEvent(ACTION_DOWN, 0, 0, 0));
        mHandwritingInitiator.startHandwriting(editText);

        verifyEditTextDrawsText(editText, null);

        editText.setText("a");
        editText.setText("");

        verifyEditTextDrawsText(editText, "hint");
    }

    private void verifyEditTextDrawsText(EditText editText, String text) {
        editText.measure(
                View.MeasureSpec.makeMeasureSpec(1024, View.MeasureSpec.AT_MOST),
                View.MeasureSpec.makeMeasureSpec(1024, View.MeasureSpec.AT_MOST));
        Canvas canvas = prepareMockCanvas(editText);
        editText.draw(canvas);
        if (text != null) {
            ArgumentCaptor<CharSequence> textCaptor = ArgumentCaptor.forClass(CharSequence.class);
            verify(canvas).drawText(
                    textCaptor.capture(), anyInt(), anyInt(), anyFloat(), anyFloat(), any());
            assertThat(textCaptor.getValue().toString()).isEqualTo(text);
        } else {
            verify(canvas, never()).drawText(
                    any(CharSequence.class), anyInt(), anyInt(), anyFloat(), anyFloat(), any());
        }
    }

    private Canvas prepareMockCanvas(View view) {
        Canvas canvas = mock(Canvas.class);
        when(canvas.getClipBounds(any())).thenAnswer(invocation -> {
            Rect outRect = invocation.getArgument(0);
            outRect.top = 0;
            outRect.left = 0;
            outRect.right = view.getMeasuredWidth();
            outRect.bottom = view.getMeasuredHeight();
            return true;
        });
        return canvas;
    }

    private MotionEvent createStylusEvent(int action, int x, int y, long eventTime) {
        MotionEvent.PointerProperties[] properties = MotionEvent.PointerProperties.createArray(1);
        properties[0].toolType = MotionEvent.TOOL_TYPE_STYLUS;