Fix rotation bug in Bluetooth pairing PIN dialog

BluetoothPairingDialogFragment has code that makes the OK button on the
dialog disabled until the user has entered at least one character into
the PIN field. However it didn't properly handle the case where the user
had entered some text and then rotated the screen - because it always
marked the OK button as disabled during onShow even if it already had
some content. This CL fixes that by looking at the text content and only
disabling the OK button if the content is empty.

Bug: 36514895
Test: make RunSettingsRoboTests
Change-Id: I4e8e70089a862e67b20ff614bbaa64fc2b641fd4
This commit is contained in:
Antony Sargent
2017-08-15 09:31:31 -07:00
parent fdbe5d9f82
commit 563c4a6557
2 changed files with 53 additions and 1 deletions

View File

@@ -25,6 +25,7 @@ import android.text.Editable;
import android.text.InputFilter;
import android.text.InputFilter.LengthFilter;
import android.text.InputType;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
@@ -34,6 +35,7 @@ import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
@@ -185,6 +187,19 @@ public class BluetoothPairingDialogFragment extends InstrumentedDialogFragment i
return dialog;
}
/**
* Helper method to return the text of the pin entry field - this exists primarily to help us
* simulate having existing text when the dialog is recreated, for example after a screen
* rotation.
*/
@VisibleForTesting
CharSequence getPairingViewText() {
if (mPairingView != null) {
return mPairingView.getText();
}
return null;
}
/**
* Returns a dialog with UI elements that allow a user to provide input.
*/
@@ -196,7 +211,9 @@ public class BluetoothPairingDialogFragment extends InstrumentedDialogFragment i
mBuilder.setNegativeButton(getString(android.R.string.cancel), this);
AlertDialog dialog = mBuilder.create();
dialog.setOnShowListener(d -> {
mDialog.getButton(Dialog.BUTTON_POSITIVE).setEnabled(false);
if (TextUtils.isEmpty(getPairingViewText())) {
mDialog.getButton(Dialog.BUTTON_POSITIVE).setEnabled(false);
}
if (mPairingView != null && mPairingView.requestFocus()) {
InputMethodManager imm = (InputMethodManager)
getContext().getSystemService(Context.INPUT_METHOD_SERVICE);

View File

@@ -28,6 +28,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
@@ -47,6 +48,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowAlertDialog;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.FragmentTestUtil;
@@ -412,6 +414,39 @@ public class BluetoothPairingDialogTest {
verify(dialogActivity, times(1)).dismiss();
}
@Test
public void rotateDialog_nullPinText_okButtonEnabled() {
userEntryDialogExistingTextTest(null);
}
@Test
public void rotateDialog_emptyPinText_okButtonEnabled() {
userEntryDialogExistingTextTest("");
}
@Test
public void rotateDialog_nonEmptyPinText_okButtonEnabled() {
userEntryDialogExistingTextTest("test");
}
// Runs a test simulating the user entry dialog type in a situation like device rotation, where
// the dialog fragment gets created and we already have some existing text entered into the
// pin field.
private void userEntryDialogExistingTextTest(CharSequence existingText) {
when(controller.getDialogType()).thenReturn(BluetoothPairingController.USER_ENTRY_DIALOG);
when(controller.getDeviceVariantMessageHintId())
.thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
when(controller.getDeviceVariantMessageId())
.thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
BluetoothPairingDialogFragment fragment = spy(new BluetoothPairingDialogFragment());
when(fragment.getPairingViewText()).thenReturn(existingText);
setupFragment(fragment);
AlertDialog dialog = ShadowAlertDialog.getLatestAlertDialog();
boolean expected = !TextUtils.isEmpty(existingText);
assertThat(dialog.getButton(Dialog.BUTTON_POSITIVE).isEnabled()).isEqualTo(expected);
}
private void setupFragment(BluetoothPairingDialogFragment frag) {
assertThat(frag.isPairingControllerSet()).isFalse();
frag.setPairingController(controller);