Prevent showing multiple keyguard dialog in vpn setup UI
Change-Id: If3a0d4ee285bfdde5f4b84bee58d62708071fe75 Fix: 37552190 Test: make RunSettingsRoboTests
This commit is contained in:
@@ -47,8 +47,8 @@ import android.widget.Toast;
|
|||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
import com.android.org.bouncycastle.asn1.ASN1InputStream;
|
import com.android.org.bouncycastle.asn1.ASN1InputStream;
|
||||||
import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
|
import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
|
||||||
import com.android.settings.password.ChooseLockGeneric;
|
|
||||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||||
|
import com.android.settings.security.ConfigureKeyGuardDialog;
|
||||||
import com.android.settings.vpn2.VpnUtils;
|
import com.android.settings.vpn2.VpnUtils;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
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
|
// This is the minimum acceptable password quality. If the current password quality is
|
||||||
// lower than this, keystore should not be activated.
|
// 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_KEY_GUARD_REQUEST = 1;
|
||||||
private static final int CONFIRM_CLEAR_SYSTEM_CREDENTIAL_REQUEST = 2;
|
private static final int CONFIRM_CLEAR_SYSTEM_CREDENTIAL_REQUEST = 2;
|
||||||
@@ -171,7 +171,8 @@ public final class CredentialStorage extends Activity {
|
|||||||
}
|
}
|
||||||
case UNLOCKED: {
|
case UNLOCKED: {
|
||||||
if (!checkKeyGuardQuality()) {
|
if (!checkKeyGuardQuality()) {
|
||||||
new ConfigureKeyGuardDialog();
|
final ConfigureKeyGuardDialog dialog = new ConfigureKeyGuardDialog();
|
||||||
|
dialog.show(getFragmentManager(), ConfigureKeyGuardDialog.TAG);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
installIfAvailable();
|
installIfAvailable();
|
||||||
@@ -190,7 +191,8 @@ public final class CredentialStorage extends Activity {
|
|||||||
private void ensureKeyGuard() {
|
private void ensureKeyGuard() {
|
||||||
if (!checkKeyGuardQuality()) {
|
if (!checkKeyGuardQuality()) {
|
||||||
// key guard not setup, doing so will initialize keystore
|
// 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
|
// will return to onResume after Activity
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -308,8 +310,7 @@ public final class CredentialStorage extends Activity {
|
|||||||
* Prompt for reset confirmation, resetting on confirmation, finishing otherwise.
|
* Prompt for reset confirmation, resetting on confirmation, finishing otherwise.
|
||||||
*/
|
*/
|
||||||
private class ResetDialog
|
private class ResetDialog
|
||||||
implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener
|
implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
|
||||||
{
|
|
||||||
private boolean mResetConfirmed;
|
private boolean mResetConfirmed;
|
||||||
|
|
||||||
private ResetDialog() {
|
private ResetDialog() {
|
||||||
@@ -323,11 +324,13 @@ public final class CredentialStorage extends Activity {
|
|||||||
dialog.show();
|
dialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void onClick(DialogInterface dialog, int button) {
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int button) {
|
||||||
mResetConfirmed = (button == DialogInterface.BUTTON_POSITIVE);
|
mResetConfirmed = (button == DialogInterface.BUTTON_POSITIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void onDismiss(DialogInterface dialog) {
|
@Override
|
||||||
|
public void onDismiss(DialogInterface dialog) {
|
||||||
if (mResetConfirmed) {
|
if (mResetConfirmed) {
|
||||||
mResetConfirmed = false;
|
mResetConfirmed = false;
|
||||||
if (confirmKeyGuard(CONFIRM_CLEAR_SYSTEM_CREDENTIAL_REQUEST)) {
|
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> {
|
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.
|
// Clear all the users credentials could have been installed in for this user.
|
||||||
new LockPatternUtils(CredentialStorage.this).resetKeyStore(UserHandle.myUserId());
|
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) {
|
if (success) {
|
||||||
Toast.makeText(CredentialStorage.this,
|
Toast.makeText(CredentialStorage.this,
|
||||||
R.string.credentials_erased, Toast.LENGTH_SHORT).show();
|
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.
|
* 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.
|
* On unsuccessful unlock, retry by calling handleUnlockOrInstall.
|
||||||
*/
|
*/
|
||||||
private class UnlockDialog implements TextWatcher,
|
private class UnlockDialog implements TextWatcher,
|
||||||
DialogInterface.OnClickListener, DialogInterface.OnDismissListener
|
DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
|
||||||
{
|
|
||||||
private boolean mUnlockConfirmed;
|
private boolean mUnlockConfirmed;
|
||||||
|
|
||||||
private final Button mButton;
|
private final Button mButton;
|
||||||
@@ -546,21 +514,26 @@ public final class CredentialStorage extends Activity {
|
|||||||
mButton.setEnabled(false);
|
mButton.setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void afterTextChanged(Editable editable) {
|
@Override
|
||||||
|
public void afterTextChanged(Editable editable) {
|
||||||
mButton.setEnabled(mOldPassword == null || mOldPassword.getText().length() > 0);
|
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);
|
mUnlockConfirmed = (button == DialogInterface.BUTTON_POSITIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void onDismiss(DialogInterface dialog) {
|
@Override
|
||||||
|
public void onDismiss(DialogInterface dialog) {
|
||||||
if (mUnlockConfirmed) {
|
if (mUnlockConfirmed) {
|
||||||
mUnlockConfirmed = false;
|
mUnlockConfirmed = false;
|
||||||
mError.setVisibility(View.VISIBLE);
|
mError.setVisibility(View.VISIBLE);
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user