Prevent showing multiple keyguard dialog in vpn setup UI

Change-Id: If3a0d4ee285bfdde5f4b84bee58d62708071fe75
Fix: 37552190
Test: make RunSettingsRoboTests
This commit is contained in:
Fan Zhang
2017-06-05 17:15:21 -07:00
parent fe23da579d
commit ab0a0c8202
3 changed files with 173 additions and 62 deletions

View File

@@ -47,8 +47,8 @@ import android.widget.Toast;
import com.android.internal.widget.LockPatternUtils;
import com.android.org.bouncycastle.asn1.ASN1InputStream;
import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.security.ConfigureKeyGuardDialog;
import com.android.settings.vpn2.VpnUtils;
import java.io.ByteArrayInputStream;
@@ -103,7 +103,7 @@ public final class CredentialStorage extends Activity {
// This is the minimum acceptable password quality. If the current password quality is
// lower than this, keystore should not be activated.
static final int MIN_PASSWORD_QUALITY = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
public static final int MIN_PASSWORD_QUALITY = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
private static final int CONFIRM_KEY_GUARD_REQUEST = 1;
private static final int CONFIRM_CLEAR_SYSTEM_CREDENTIAL_REQUEST = 2;
@@ -171,7 +171,8 @@ public final class CredentialStorage extends Activity {
}
case UNLOCKED: {
if (!checkKeyGuardQuality()) {
new ConfigureKeyGuardDialog();
final ConfigureKeyGuardDialog dialog = new ConfigureKeyGuardDialog();
dialog.show(getFragmentManager(), ConfigureKeyGuardDialog.TAG);
return;
}
installIfAvailable();
@@ -190,7 +191,8 @@ public final class CredentialStorage extends Activity {
private void ensureKeyGuard() {
if (!checkKeyGuardQuality()) {
// key guard not setup, doing so will initialize keystore
new ConfigureKeyGuardDialog();
final ConfigureKeyGuardDialog dialog = new ConfigureKeyGuardDialog();
dialog.show(getFragmentManager(), ConfigureKeyGuardDialog.TAG);
// will return to onResume after Activity
return;
}
@@ -308,8 +310,7 @@ public final class CredentialStorage extends Activity {
* Prompt for reset confirmation, resetting on confirmation, finishing otherwise.
*/
private class ResetDialog
implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener
{
implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
private boolean mResetConfirmed;
private ResetDialog() {
@@ -323,11 +324,13 @@ public final class CredentialStorage extends Activity {
dialog.show();
}
@Override public void onClick(DialogInterface dialog, int button) {
@Override
public void onClick(DialogInterface dialog, int button) {
mResetConfirmed = (button == DialogInterface.BUTTON_POSITIVE);
}
@Override public void onDismiss(DialogInterface dialog) {
@Override
public void onDismiss(DialogInterface dialog) {
if (mResetConfirmed) {
mResetConfirmed = false;
if (confirmKeyGuard(CONFIRM_CLEAR_SYSTEM_CREDENTIAL_REQUEST)) {
@@ -344,7 +347,8 @@ public final class CredentialStorage extends Activity {
*/
private class ResetKeyStoreAndKeyChain extends AsyncTask<Void, Void, Boolean> {
@Override protected Boolean doInBackground(Void... unused) {
@Override
protected Boolean doInBackground(Void... unused) {
// Clear all the users credentials could have been installed in for this user.
new LockPatternUtils(CredentialStorage.this).resetKeyStore(UserHandle.myUserId());
@@ -364,7 +368,8 @@ public final class CredentialStorage extends Activity {
}
}
@Override protected void onPostExecute(Boolean success) {
@Override
protected void onPostExecute(Boolean success) {
if (success) {
Toast.makeText(CredentialStorage.this,
R.string.credentials_erased, Toast.LENGTH_SHORT).show();
@@ -385,42 +390,6 @@ public final class CredentialStorage extends Activity {
}
}
/**
* Prompt for key guard configuration confirmation.
*/
private class ConfigureKeyGuardDialog
implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener
{
private boolean mConfigureConfirmed;
private ConfigureKeyGuardDialog() {
AlertDialog dialog = new AlertDialog.Builder(CredentialStorage.this)
.setTitle(android.R.string.dialog_alert_title)
.setMessage(R.string.credentials_configure_lock_screen_hint)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
.create();
dialog.setOnDismissListener(this);
dialog.show();
}
@Override public void onClick(DialogInterface dialog, int button) {
mConfigureConfirmed = (button == DialogInterface.BUTTON_POSITIVE);
}
@Override public void onDismiss(DialogInterface dialog) {
if (mConfigureConfirmed) {
mConfigureConfirmed = false;
Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
MIN_PASSWORD_QUALITY);
startActivity(intent);
return;
}
finish();
}
}
/**
* Check that the caller is either certinstaller or Settings running in a profile of this user.
*/
@@ -506,8 +475,7 @@ public final class CredentialStorage extends Activity {
* On unsuccessful unlock, retry by calling handleUnlockOrInstall.
*/
private class UnlockDialog implements TextWatcher,
DialogInterface.OnClickListener, DialogInterface.OnDismissListener
{
DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
private boolean mUnlockConfirmed;
private final Button mButton;
@@ -546,21 +514,26 @@ public final class CredentialStorage extends Activity {
mButton.setEnabled(false);
}
@Override public void afterTextChanged(Editable editable) {
@Override
public void afterTextChanged(Editable editable) {
mButton.setEnabled(mOldPassword == null || mOldPassword.getText().length() > 0);
}
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override public void onTextChanged(CharSequence s,int start, int before, int count) {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override public void onClick(DialogInterface dialog, int button) {
@Override
public void onClick(DialogInterface dialog, int button) {
mUnlockConfirmed = (button == DialogInterface.BUTTON_POSITIVE);
}
@Override public void onDismiss(DialogInterface dialog) {
@Override
public void onDismiss(DialogInterface dialog) {
if (mUnlockConfirmed) {
mUnlockConfirmed = false;
mError.setVisibility(View.VISIBLE);

View File

@@ -0,0 +1,85 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.security;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.admin.DevicePolicyManager;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.CredentialStorage;
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.password.ChooseLockGeneric;
/**
* Prompt for key guard configuration confirmation.
*/
public class ConfigureKeyGuardDialog extends InstrumentedDialogFragment
implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
public static final String TAG = "ConfigureKeyGuardDialog";
private boolean mConfigureConfirmed;
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.CONFIGURE_KEYGUARD_DIALOG;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setTitle(android.R.string.dialog_alert_title)
.setMessage(R.string.credentials_configure_lock_screen_hint)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
.create();
}
@Override
public void onClick(DialogInterface dialog, int button) {
mConfigureConfirmed = (button == DialogInterface.BUTTON_POSITIVE);
}
@Override
public void onDismiss(DialogInterface dialog) {
if (mConfigureConfirmed) {
mConfigureConfirmed = false;
startPasswordSetup();
return;
} else {
final Activity activity = getActivity();
if (activity != null) {
activity.finish();
}
}
}
@VisibleForTesting
void startPasswordSetup() {
Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
CredentialStorage.MIN_PASSWORD_QUALITY);
startActivity(intent);
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.security;
import android.content.DialogInterface;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.testutils.shadow.ShadowEventLogWriter;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Config;
import org.robolectric.util.FragmentController;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class ConfigureKeyGuardDialogTest {
@Test
@Config(shadows = ShadowEventLogWriter.class)
public void displayDialog_clickPositiveButton_launchSetNewPassword() {
final FragmentController<ConfigureKeyGuardDialog> fragmentController =
Robolectric.buildFragment(ConfigureKeyGuardDialog.class);
final ConfigureKeyGuardDialog fragment = spy(fragmentController.get());
doNothing().when(fragment).startPasswordSetup();
fragmentController.attach().create().start().resume();
fragment.onClick(null /* dialog */, DialogInterface.BUTTON_POSITIVE);
fragment.onDismiss(null /* dialog */);
verify(fragment).startPasswordSetup();
}
}