From 9be8c3fbfe39a5259c5f8c6adce67fbc5907c802 Mon Sep 17 00:00:00 2001 From: Antony Sargent Date: Thu, 7 Sep 2017 16:19:17 -0700 Subject: [PATCH] Fix focus behavior of ValidatedEditTextPreference The bug report was that the cursor is set to the beginning of the EditText for wifi hotspot password field, instead of at the end (or having the entire field selected). This fix makes it so that all ValidatedEditTextPreference's will put the cursor at the end of the EditText. Bug: 65413206 Test: make RunSettingsRoboTests Change-Id: I23f3bb1b3f1b49b2f193c0ae2e103eae5c1a1019 --- .../widget/ValidatedEditTextPreference.java | 23 +++++++------ .../ValidatedEditTextPreferenceTest.java | 33 +++++++++++++++++-- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/com/android/settings/widget/ValidatedEditTextPreference.java b/src/com/android/settings/widget/ValidatedEditTextPreference.java index 76331d4f97e..58c62ebce84 100644 --- a/src/com/android/settings/widget/ValidatedEditTextPreference.java +++ b/src/com/android/settings/widget/ValidatedEditTextPreference.java @@ -21,8 +21,10 @@ import android.content.Context; import android.support.annotation.VisibleForTesting; import android.text.Editable; import android.text.InputType; +import android.text.TextUtils; import android.text.TextWatcher; import android.util.AttributeSet; +import android.util.Log; import android.view.View; import android.widget.EditText; @@ -61,17 +63,18 @@ public class ValidatedEditTextPreference extends CustomEditTextPreference { @Override protected void onBindDialogView(View view) { super.onBindDialogView(view); - if (mValidator != null) { - final EditText editText = view.findViewById(android.R.id.edit); - if (editText != null) { - editText.removeTextChangedListener(mTextWatcher); - if (mIsPassword) { - editText.setInputType( - InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); - editText.setMaxLines(1); - } - editText.addTextChangedListener(mTextWatcher); + final EditText editText = view.findViewById(android.R.id.edit); + if (editText != null && !TextUtils.isEmpty(editText.getText())) { + editText.setSelection(editText.getText().length()); + } + if (mValidator != null && editText != null) { + editText.removeTextChangedListener(mTextWatcher); + if (mIsPassword) { + editText.setInputType( + InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + editText.setMaxLines(1); } + editText.addTextChangedListener(mTextWatcher); } } diff --git a/tests/robotests/src/com/android/settings/widget/ValidatedEditTextPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/ValidatedEditTextPreferenceTest.java index 88a51474187..e061787483d 100644 --- a/tests/robotests/src/com/android/settings/widget/ValidatedEditTextPreferenceTest.java +++ b/tests/robotests/src/com/android/settings/widget/ValidatedEditTextPreferenceTest.java @@ -35,9 +35,10 @@ import org.robolectric.annotation.Config; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; @RunWith(SettingsRobolectricTestRunner.class) @@ -58,10 +59,36 @@ public class ValidatedEditTextPreferenceTest { } @Test - public void bindDialogView_noTextWatcher_shouldDoNothing() { + public void bindDialogView_nullEditText_shouldNotCrash() { + when(mView.findViewById(android.R.id.edit)).thenReturn(null); + // should not crash trying to get the EditText text + mPreference.onBindDialogView(mView); + } + + @Test + public void bindDialogView_emptyEditText_shouldNotSetSelection() { + final String testText = ""; + final EditText editText = spy(new EditText(RuntimeEnvironment.application)); + editText.setText(testText); + when(mView.findViewById(android.R.id.edit)).thenReturn(editText); + mPreference.onBindDialogView(mView); - verifyZeroInteractions(mView); + // no need to setSelection if text was empty + verify(editText, never()).setSelection(anyInt()); + } + + @Test + public void bindDialogView_nonemptyEditText_shouldSetSelection() { + final String testText = "whatever"; + final EditText editText = spy(new EditText(RuntimeEnvironment.application)); + editText.setText(testText); + when(mView.findViewById(android.R.id.edit)).thenReturn(editText); + + mPreference.onBindDialogView(mView); + + // selection should be set to end of string + verify(editText).setSelection(testText.length()); } @Test