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

Commit 3aab6c13 authored by Brian Lee's avatar Brian Lee
Browse files

Use footer bar button to skip remote LSKF validation for expressive

theme

Additional changes:
* Refactored showCancelButton evaluation logic
* Renamed confusing "enable" variable in
  `updateRemoteLockscreenValidationViews`

Flag: EXEMPT for expressive style customization
Bug: 415202233
Test: atest ConfirmLockPasswordTest
Test: atest ConfirmLockPatternTest
Test: atest ConfirmCredentialTest
Test: Manually went through Remote LSKF validation flow in SUW and
confirmed LSKF in Settings

Change-Id: I93b81d6c0c793bfc25007bde293cf9aa1dd92234
parent 117a3601
Loading
Loading
Loading
Loading
+50 −19
Original line number Diff line number Diff line
@@ -57,7 +57,10 @@ import com.android.internal.widget.LockscreenCredential;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.InstrumentedFragment;
import com.android.settingslib.widget.SettingsThemeHelper;

import com.google.android.setupcompat.template.FooterBarMixin;
import com.google.android.setupcompat.template.FooterButton;
import com.google.android.setupdesign.GlifLayout;

/**
@@ -108,6 +111,7 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
    protected boolean mRemoteValidation;
    protected boolean mRequestWriteRepairModePassword;
    protected boolean mRepairMode;
    protected boolean mExpressiveTheme;
    protected CharSequence mAlternateButtonText;
    protected BiometricManager mBiometricManager;
    @Nullable protected RemoteLockscreenValidationSession mRemoteLockscreenValidationSession;
@@ -115,6 +119,7 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
    @Nullable protected RemoteLockscreenValidationClient mRemoteLockscreenValidationClient;
    protected RemoteLockscreenValidationFragment mRemoteLockscreenValidationFragment;
    @Nullable protected SaveAndFinishWorker mSaveAndFinishWorker;
    @Nullable protected FooterBarMixin mFooterBarMixin;

    private boolean isInternalActivity() {
        return (getActivity() instanceof ConfirmLockPassword.InternalActivity)
@@ -194,29 +199,49 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
        mDevicePolicyManager = (DevicePolicyManager) getActivity().getSystemService(
                Context.DEVICE_POLICY_SERVICE);
        mBiometricManager = getActivity().getSystemService(BiometricManager.class);
        mExpressiveTheme = SettingsThemeHelper.isExpressiveTheme(getActivity());
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mCancelButton = view.findViewById(R.id.cancelButton);
        boolean showCancelButton = mRemoteValidation || getActivity().getIntent().getBooleanExtra(
                SHOW_CANCEL_BUTTON, false);
        boolean hasAlternateButton = (mFrp || mRemoteValidation || mRepairMode)
        boolean hasAlternateButton =
                (mFrp || mRemoteValidation || mRepairMode)
                        && !TextUtils.isEmpty(mAlternateButtonText);
        mCancelButton.setVisibility(showCancelButton || hasAlternateButton
                ? View.VISIBLE : View.GONE);
        boolean showCancelButton =
                mRemoteValidation
                        || getActivity().getIntent().getBooleanExtra(SHOW_CANCEL_BUTTON, false)
                        || hasAlternateButton;
        mFooterBarMixin = mGlifLayout.getMixin(FooterBarMixin.class);
        if (mExpressiveTheme && showCancelButton && mFooterBarMixin != null && mRemoteValidation) {
            mFooterBarMixin.setSecondaryButton(
                    new FooterButton.Builder(getActivity())
                        .setButtonType(FooterButton.ButtonType.CANCEL)
                        .setText(hasAlternateButton
                                ? mAlternateButtonText.toString()
                                : getString(R.string.cancel))
                        .setListener(v -> onRemoteLockscreenValidationFailure(
                                "Forgot lockscreen credential button pressed."))
                        .build());
            // Remove the cancel button since the footer bar button is used instead
            mCancelButton.setVisibility(View.GONE);
        } else {
            mCancelButton.setVisibility(showCancelButton ? View.VISIBLE : View.GONE);
            if (hasAlternateButton) {
                mCancelButton.setText(mAlternateButtonText);
            }
        mCancelButton.setOnClickListener(v -> {
            mCancelButton.setOnClickListener(
                    v -> {
                        if (hasAlternateButton) {
                            getActivity().setResult(KeyguardManager.RESULT_ALTERNATE);
                            getActivity().finish();
                        } else if (mRemoteValidation) {
                onRemoteLockscreenValidationFailure("Forgot lockscreen credential button pressed.");
                            onRemoteLockscreenValidationFailure(
                                    "Forgot lockscreen credential button pressed.");
                        }
                    });
        }
        setupForgotButtonIfManagedProfile(view);

        mCheckBox = view.findViewById(R.id.checkbox);
@@ -441,10 +466,16 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
            return;
        }

        boolean enable = mRemoteLockscreenValidationFragment.isRemoteValidationInProgress();
        mGlifLayout.setProgressBarShown(enable);
        mCheckBox.setEnabled(!enable);
        mCancelButton.setEnabled(!enable);
        boolean inProgress = mRemoteLockscreenValidationFragment.isRemoteValidationInProgress();
        mGlifLayout.setProgressBarShown(inProgress);
        if (mExpressiveTheme
                && mFooterBarMixin != null
                && mFooterBarMixin.getSecondaryButton() != null) {
            mFooterBarMixin.getSecondaryButton().setEnabled(!inProgress);
        } else {
            mCancelButton.setEnabled(!inProgress);
        }
        mCheckBox.setEnabled(!inProgress);
    }

    /**
+15 −4
Original line number Diff line number Diff line
@@ -251,10 +251,21 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
                            ? getDefaultCheckboxLabel()
                            : mCheckBoxLabel);
                }
                if (mCancelButton != null && TextUtils.isEmpty(mAlternateButtonText)) {
                    mCancelButton.setText(mIsAlpha
                if (TextUtils.isEmpty(mAlternateButtonText)) {
                    int forgotLockPasswordResId =
                            mIsAlpha
                                    ? R.string.lockpassword_forgot_password
                            : R.string.lockpassword_forgot_pin);
                                    : R.string.lockpassword_forgot_pin;
                    if (mExpressiveTheme
                            && mFooterBarMixin != null
                            && mFooterBarMixin.getSecondaryButton() != null) {
                        mFooterBarMixin
                                .getSecondaryButton()
                                .setText(getActivity(), forgotLockPasswordResId);

                    } else if (mCancelButton != null) {
                        mCancelButton.setText(forgotLockPasswordResId);
                    }
                }
                updateRemoteLockscreenValidationViews();
            }
+11 −2
Original line number Diff line number Diff line
@@ -236,8 +236,17 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
                            ? getDefaultCheckboxLabel()
                            : mCheckBoxLabel);
                }
                if (mCancelButton != null && TextUtils.isEmpty(mAlternateButtonText)) {
                    mCancelButton.setText(R.string.lockpassword_forgot_pattern);
                if (TextUtils.isEmpty(mAlternateButtonText)) {
                    int forgotLockPasswordResId = R.string.lockpassword_forgot_pattern;
                    if (mExpressiveTheme
                            && mFooterBarMixin != null
                            && mFooterBarMixin.getSecondaryButton() != null) {
                        mFooterBarMixin
                                .getSecondaryButton()
                                .setText(getActivity(), forgotLockPasswordResId);
                    } else if (mCancelButton != null) {
                        mCancelButton.setText(forgotLockPasswordResId);
                    }
                }
                updateRemoteLockscreenValidationViews();
            }
+44 −0
Original line number Diff line number Diff line
@@ -34,7 +34,10 @@ import android.app.admin.ManagedSubscriptionsPolicy;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.util.FeatureFlagUtils;
import android.view.View;

import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
@@ -45,9 +48,11 @@ import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settingslib.widget.theme.flags.Flags;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
@@ -67,6 +72,9 @@ import org.robolectric.shadows.ShadowApplicationPackageManager;
})
public class ConfirmCredentialTest {

    @Rule
    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();

    private Context mContext;
    private ShadowApplicationPackageManager mShadowApplicationPackageManager;

@@ -175,6 +183,42 @@ public class ConfirmCredentialTest {
        assertThat(activity.isFinishing()).isTrue();
    }

    @Test
    public void normalCredentialConfirmation_noCancelButton() {
        ConfirmDeviceCredentialBaseActivity activity =
                buildConfirmDeviceCredentialBaseActivity(ConfirmLockPassword.class, new Intent());
        ConfirmDeviceCredentialBaseFragment fragment =
                getConfirmDeviceCredentialBaseFragment(activity);

        assertThat(fragment.mFooterBarMixin.getButtonContainer()).isNull();
        assertThat(fragment.mCancelButton.getVisibility()).isEqualTo(View.GONE);
    }

    @Test
    public void remoteValidation_usesCancelButton() throws Exception {
        ConfirmDeviceCredentialBaseActivity activity = buildConfirmDeviceCredentialBaseActivity(
                ConfirmLockPassword.class, createRemoteLockscreenValidationIntent(
                        KeyguardManager.PASSWORD, VALID_REMAINING_ATTEMPTS));
        ConfirmDeviceCredentialBaseFragment fragment =
                getConfirmDeviceCredentialBaseFragment(activity);

        assertThat(fragment.mFooterBarMixin.getButtonContainer()).isNull();
        assertThat(fragment.mCancelButton.getVisibility()).isEqualTo(View.VISIBLE);
    }

    @Test
    @EnableFlags(Flags.FLAG_IS_EXPRESSIVE_DESIGN_ENABLED)
    public void remoteValidation_expressiveTheme_usesFooterBarButton() throws Exception {
        ConfirmDeviceCredentialBaseActivity activity = buildConfirmDeviceCredentialBaseActivity(
                ConfirmLockPassword.class, createRemoteLockscreenValidationIntent(
                        KeyguardManager.PASSWORD, VALID_REMAINING_ATTEMPTS));
        ConfirmDeviceCredentialBaseFragment fragment =
                getConfirmDeviceCredentialBaseFragment(activity);

        assertThat(fragment.mFooterBarMixin.getSecondaryButton()).isNotNull();
        assertThat(fragment.mCancelButton.getVisibility()).isEqualTo(View.GONE);
    }

    @Test
    public void testLastTryDialogShownExactlyOnce() {
        FragmentManager fm = Robolectric.buildActivity(FragmentActivity.class).