Loading src/com/android/settings/CredentialStorage.java +35 −62 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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; } Loading Loading @@ -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() { Loading @@ -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)) { Loading @@ -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()); Loading @@ -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(); Loading @@ -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. */ Loading Loading @@ -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; Loading Loading @@ -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); Loading src/com/android/settings/security/ConfigureKeyGuardDialog.java 0 → 100644 +85 −0 Original line number Diff line number Diff line /* * 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); } } tests/robotests/src/com/android/settings/security/ConfigureKeyGuardDialogTest.java 0 → 100644 +53 −0 Original line number Diff line number Diff line /* * 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(); } } Loading
src/com/android/settings/CredentialStorage.java +35 −62 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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; } Loading Loading @@ -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() { Loading @@ -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)) { Loading @@ -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()); Loading @@ -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(); Loading @@ -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. */ Loading Loading @@ -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; Loading Loading @@ -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); Loading
src/com/android/settings/security/ConfigureKeyGuardDialog.java 0 → 100644 +85 −0 Original line number Diff line number Diff line /* * 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); } }
tests/robotests/src/com/android/settings/security/ConfigureKeyGuardDialogTest.java 0 → 100644 +53 −0 Original line number Diff line number Diff line /* * 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(); } }