Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c3ff66e4 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Prevent showing multiple keyguard dialog in vpn setup UI"

parents 70acb677 ab0a0c82
Loading
Loading
Loading
Loading
+35 −62
Original line number Diff line number Diff line
@@ -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);
+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);
    }
}
+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();
    }
}