[Biometric Onboarding & Edu] Update face settings page

- Added a feature provider for face settings page in FaceFeatureProvider
  for customization
- When face is deleted, disabled the settings buttons instead of hiding
  them.
- Updated new UX style for add/remove face button.

Bug: 370940762
Test: atest FaceSettingsEnrollButtonPreferenceControllerTest
            FaceSettingsFooterPreferenceControllerTest
Test: manual - 1. Enroll face
               2. Go Face Settings page and remove face
	       3. Enroll face again
Flag: com.android.settings.flags.biometrics_onboarding_education

Change-Id: I490e647523eeff2dd1a58aab07f638e3e5e0ffb8
This commit is contained in:
Shawn Lin
2025-01-27 05:16:39 +00:00
parent d6e99d3783
commit d747235a4c
14 changed files with 394 additions and 54 deletions

View File

@@ -42,4 +42,13 @@ public interface FaceFeatureProvider {
default FaceEnrollActivityClassProvider getEnrollActivityClassProvider() {
return FaceEnrollActivityClassProvider.getInstance();
}
/**
* Gets the feature provider for FaceSettings page
* @return the provider
*/
@NonNull
default FaceSettingsFeatureProvider getFaceSettingsFeatureProvider() {
return FaceSettingsFeatureProvider.getInstance();
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2025 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.biometrics.face;
import android.content.Context;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.settings.R;
import com.android.settingslib.widget.TwoTargetPreference;
public class FacePreference extends TwoTargetPreference {
public FacePreference(@NonNull Context context) {
super(context);
}
public FacePreference(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public FacePreference(
@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public FacePreference(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected int getSecondTargetResId() {
return R.layout.preference_widget_delete;
}
}

View File

@@ -30,6 +30,7 @@ import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
import android.content.res.ResourceId;
import android.hardware.face.FaceManager;
import android.os.Bundle;
import android.os.UserHandle;
@@ -73,12 +74,19 @@ public class FaceSettings extends DashboardFragment {
private static final String KEY_BIOMETRICS_SUCCESSFULLY_AUTHENTICATED =
"biometrics_successfully_authenticated";
private static final String PREF_KEY_FACE_DESCRIPTION = "security_settings_face_description";
private static final String PREF_KEY_DELETE_FACE_DATA =
"security_settings_face_delete_faces_container";
private static final String PREF_KEY_ENROLL_FACE_UNLOCK =
"security_settings_face_enroll_faces_container";
private static final String PREF_KEY_USE_FACE_TO_CATEGORY =
"biometric_settings_use_face_to";
private static final String PREF_KEY_FACE_ENROLLED_CATEGORY =
"security_settings_face_enrolled_category";
private static final String PREF_KEY_FACE_REMOVE =
"security_settings_face_remove";
private static final String PREF_KEY_FACE_ENROLL =
"security_settings_face_enroll";
public static final String SECURITY_SETTINGS_FACE_MANAGE_CATEGORY =
"security_settings_face_manage_category";
@@ -98,6 +106,9 @@ public class FaceSettings extends DashboardFragment {
private List<Preference> mTogglePreferences;
private Preference mRemoveButton;
private Preference mEnrollButton;
private PreferenceCategory mFaceEnrolledCategory;
private Preference mFaceRemoveButton;
private Preference mFaceEnrollButton;
private FaceFeatureProvider mFaceFeatureProvider;
private boolean mConfirmingPassword;
@@ -111,8 +122,7 @@ public class FaceSettings extends DashboardFragment {
}
// Hide the "remove" button and show the "set up face authentication" button.
mRemoveButton.setVisible(false);
mEnrollButton.setVisible(true);
updateFaceAddAndRemovePreference(false);
};
private final FaceSettingsEnrollButtonPreferenceController.Listener mEnrollListener = intent ->
@@ -193,6 +203,15 @@ public class FaceSettings extends DashboardFragment {
: use(FaceSettingsLockscreenBypassPreferenceController.class);
mLockscreenController.setUserId(mUserId);
final int descriptionResId = FeatureFactory.getFeatureFactory()
.getFaceFeatureProvider().getFaceSettingsFeatureProvider()
.getSettingPageDescription();
if (ResourceId.isValid(descriptionResId)) {
final Preference preference = findPreference(PREF_KEY_FACE_DESCRIPTION);
preference.setTitle(descriptionResId);
preference.setVisible(true);
}
final PreferenceCategory managePref =
findPreference(SECURITY_SETTINGS_FACE_MANAGE_CATEGORY);
Preference keyguardPref = findPreference(FaceSettingsKeyguardPreferenceController.KEY);
@@ -201,8 +220,13 @@ public class FaceSettings extends DashboardFragment {
Preference confirmPref = findPreference(FaceSettingsConfirmPreferenceController.KEY);
Preference bypassPref =
findPreference(mLockscreenController.getPreferenceKey());
Preference unlockKeyguard = findPreference(
use(FaceSettingsKeyguardUnlockPreferenceController.class).getPreferenceKey());
Preference appsPref = findPreference(
use(FaceSettingsAppsPreferenceController.class).getPreferenceKey());
mTogglePreferences = new ArrayList<>(
Arrays.asList(keyguardPref, appPref, attentionPref, confirmPref, bypassPref));
Arrays.asList(keyguardPref, appPref, attentionPref, confirmPref, bypassPref,
unlockKeyguard, appsPref));
if (RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
getContext(), DevicePolicyManager.KEYGUARD_DISABLE_FACE, mUserId) != null) {
@@ -215,9 +239,18 @@ public class FaceSettings extends DashboardFragment {
mRemoveButton = findPreference(FaceSettingsRemoveButtonPreferenceController.KEY);
mEnrollButton = findPreference(FaceSettingsEnrollButtonPreferenceController.KEY);
mFaceEnrolledCategory = findPreference(PREF_KEY_FACE_ENROLLED_CATEGORY);
mFaceRemoveButton = findPreference(PREF_KEY_FACE_REMOVE);
mFaceRemoveButton.setIcon(R.drawable.ic_face);
mFaceRemoveButton.setOnPreferenceClickListener(
use(FaceSettingsRemoveButtonPreferenceController.class));
mFaceEnrollButton = findPreference(PREF_KEY_FACE_ENROLL);
mFaceEnrollButton.setIcon(R.drawable.ic_add_24dp);
mFaceEnrollButton.setOnPreferenceClickListener(
use(FaceSettingsEnrollButtonPreferenceController.class));
final boolean hasEnrolled = mFaceManager.hasEnrolledTemplates(mUserId);
mEnrollButton.setVisible(!hasEnrolled);
mRemoveButton.setVisible(hasEnrolled);
updateFaceAddAndRemovePreference(hasEnrolled);
// There is no better way to do this :/
for (AbstractPreferenceController controller : mControllers) {
@@ -255,8 +288,7 @@ public class FaceSettings extends DashboardFragment {
public void onStart() {
super.onStart();
final boolean hasEnrolled = mFaceManager.hasEnrolledTemplates(mUserId);
mEnrollButton.setVisible(!hasEnrolled);
mRemoveButton.setVisible(hasEnrolled);
updateFaceAddAndRemovePreference(hasEnrolled);
// When the user has face id registered but failed enrolling in device lock state,
// lead users directly to the confirm deletion dialog in Face Unlock settings.
@@ -264,10 +296,16 @@ public class FaceSettings extends DashboardFragment {
final boolean isReEnrollFaceUnlock = getIntent().getBooleanExtra(
FaceSettings.KEY_RE_ENROLL_FACE, false);
if (isReEnrollFaceUnlock) {
final Button removeBtn = ((LayoutPreference) mRemoveButton).findViewById(
R.id.security_settings_face_settings_remove_button);
if (removeBtn != null && removeBtn.isEnabled()) {
mRemoveController.onClick(removeBtn);
if (Flags.biometricsOnboardingEducation()) {
if (mFaceRemoveButton.isEnabled()) {
mRemoveController.onPreferenceClick(mFaceRemoveButton);
}
} else {
final Button removeBtn = ((LayoutPreference) mRemoveButton).findViewById(
R.id.security_settings_face_settings_remove_button);
if (removeBtn != null && removeBtn.isEnabled()) {
mRemoveController.onClick(removeBtn);
}
}
}
}
@@ -327,8 +365,7 @@ public class FaceSettings extends DashboardFragment {
});
final boolean hasEnrolled = mFaceManager.hasEnrolledTemplates(mUserId);
mEnrollButton.setVisible(!hasEnrolled);
mRemoveButton.setVisible(hasEnrolled);
updateFaceAddAndRemovePreference(hasEnrolled);
final Utils.BiometricStatus biometricAuthStatus =
Utils.requestBiometricAuthenticationForMandatoryBiometrics(getActivity(),
mBiometricsAuthenticationRequested,
@@ -407,6 +444,17 @@ public class FaceSettings extends DashboardFragment {
return mControllers;
}
private void updateFaceAddAndRemovePreference(boolean hasEnrolled) {
if (Flags.biometricsOnboardingEducation()) {
mFaceEnrolledCategory.setVisible(true);
mFaceRemoveButton.setVisible(hasEnrolled);
mFaceEnrollButton.setVisible(!hasEnrolled);
} else {
mEnrollButton.setVisible(!hasEnrolled);
mRemoveButton.setVisible(hasEnrolled);
}
}
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new FaceSettingsKeyguardPreferenceController(context));

View File

@@ -23,6 +23,7 @@ import android.hardware.face.FaceManager;
import android.provider.Settings;
import androidx.annotation.NonNull;
import androidx.preference.Preference;
import com.android.settings.Utils;
import com.android.settings.biometrics.activeunlock.ActiveUnlockStatusUtils;
@@ -52,6 +53,20 @@ public class FaceSettingsAppsPreferenceController extends
isChecked ? ON : OFF, getUserId());
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
if (!FaceSettings.isFaceHardwareDetected(mContext)) {
preference.setEnabled(false);
} else if (!mFaceManager.hasEnrolledTemplates(getUserId())) {
preference.setEnabled(false);
} else if (getRestrictingAdmin() != null) {
preference.setEnabled(false);
} else {
preference.setEnabled(true);
}
}
@Override
public int getAvailabilityStatus() {
final ActiveUnlockStatusUtils activeUnlockStatusUtils =

View File

@@ -24,10 +24,12 @@ import android.content.Intent;
import android.view.View;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.flags.Flags;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.widget.LayoutPreference;
@@ -39,10 +41,11 @@ import com.google.android.setupdesign.util.PartnerStyleHelper;
* Preference controller that allows a user to enroll their face.
*/
public class FaceSettingsEnrollButtonPreferenceController extends BasePreferenceController
implements View.OnClickListener {
implements View.OnClickListener, Preference.OnPreferenceClickListener {
private static final String TAG = "FaceSettings/Remove";
static final String KEY = "security_settings_face_enroll_faces_container";
static final String KEY_1 = "security_settings_face_enroll";
private final Context mContext;
@@ -53,7 +56,7 @@ public class FaceSettingsEnrollButtonPreferenceController extends BasePreference
private Listener mListener;
public FaceSettingsEnrollButtonPreferenceController(Context context) {
this(context, KEY);
this(context, Flags.biometricsOnboardingEducation() ? KEY_1 : KEY);
}
public FaceSettingsEnrollButtonPreferenceController(Context context, String preferenceKey) {
@@ -62,25 +65,39 @@ public class FaceSettingsEnrollButtonPreferenceController extends BasePreference
}
@Override
public void updateState(Preference preference) {
public void updateState(@NonNull Preference preference) {
super.updateState(preference);
mButton = ((LayoutPreference) preference).findViewById(
R.id.security_settings_face_settings_enroll_button);
if (PartnerStyleHelper.shouldApplyPartnerResource(mButton)) {
ButtonStyler.applyPartnerCustomizationPrimaryButtonStyle(mContext, mButton);
}
mButton.setOnClickListener(this);
final boolean isDeviceOwnerBlockingAuth =
RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
mContext, DevicePolicyManager.KEYGUARD_DISABLE_FACE, mUserId) != null;
mButton.setEnabled(!isDeviceOwnerBlockingAuth);
if (Flags.biometricsOnboardingEducation()) {
preference.setEnabled(!isDeviceOwnerBlockingAuth);
} else {
mButton = ((LayoutPreference) preference).findViewById(
R.id.security_settings_face_settings_enroll_button);
if (PartnerStyleHelper.shouldApplyPartnerResource(mButton)) {
ButtonStyler.applyPartnerCustomizationPrimaryButtonStyle(mContext, mButton);
}
mButton.setOnClickListener(this);
mButton.setEnabled(!isDeviceOwnerBlockingAuth);
}
}
@Override
public void onClick(View v) {
startEnrolling();
}
@Override
public boolean onPreferenceClick(@NonNull Preference preference) {
startEnrolling();
return true;
}
private void startEnrolling() {
mIsClicked = true;
final Intent intent = new Intent();
intent.setClassName(SETTINGS_PACKAGE_NAME, FaceEnroll.class.getName());

View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2025 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.biometrics.face
/**
* Provide features for FaceSettings page.
*/
open class FaceSettingsFeatureProvider {
/**
* Get the description shown in the Face settings page.
*/
open fun getSettingPageDescription(): Int {
return 0
}
/**
* Get the footer description for face class3 shown in the Face settings page.
*/
open fun getSettingPageFooterDescriptionClass3(): Int {
return com.android.settings.R.string.security_settings_face_settings_footer_class3
}
/**
* Get the footer learn more description shown in the Face settings page.
*/
open fun getSettingPageFooterLearnMoreDescription(): Int {
return 0
}
/**
* Get the footer learn more URL.
*/
open fun getSettingPageFooterLearnMoreUrl(): Int {
return 0
}
companion object {
@JvmStatic
val instance = FaceSettingsFeatureProvider()
}
}

View File

@@ -19,11 +19,13 @@ package com.android.settings.biometrics.face;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.ResourceId;
import android.hardware.biometrics.SensorProperties;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.face.IFaceAuthenticatorsRegisteredCallback;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.preference.Preference;
@@ -35,6 +37,7 @@ import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.utils.AnnotationSpan;
import com.android.settingslib.HelpUtils;
import com.android.settingslib.widget.FooterPreference;
import java.util.List;
@@ -82,14 +85,15 @@ public class FaceSettingsFooterPreferenceController extends BasePreferenceContro
mContext, mContext.getString(R.string.help_url_face), getClass().getName());
final AnnotationSpan.LinkInfo linkInfo =
new AnnotationSpan.LinkInfo(mContext, ANNOTATION_URL, helpIntent);
int footerRes;
final FaceSettingsFeatureProvider featureProvider = FeatureFactory.getFeatureFactory()
.getFaceFeatureProvider().getFaceSettingsFeatureProvider();
final int footerRes;
boolean isAttentionSupported = mProvider.isAttentionSupported(mContext);
if (Utils.isPrivateProfile(mUserId, mContext)) {
footerRes = R.string.private_space_face_settings_footer;
} else if (mIsFaceStrong) {
footerRes = isAttentionSupported
? R.string.security_settings_face_settings_footer_class3
? featureProvider.getSettingPageFooterDescriptionClass3()
: R.string.security_settings_face_settings_footer_attention_not_supported;
} else {
footerRes = isAttentionSupported
@@ -98,6 +102,20 @@ public class FaceSettingsFooterPreferenceController extends BasePreferenceContro
}
preference.setTitle(AnnotationSpan.linkify(
mContext.getText(footerRes), linkInfo));
final int learnMoreRes = featureProvider.getSettingPageFooterLearnMoreDescription();
final int learnMoreUrlRes = featureProvider.getSettingPageFooterLearnMoreUrl();
if (ResourceId.isValid(learnMoreRes)
&& ResourceId.isValid(learnMoreUrlRes)
&& preference instanceof FooterPreference) {
final Intent learnMoreIntent = HelpUtils.getHelpIntent(
mContext, mContext.getString(learnMoreUrlRes), getClass().getName());
final View.OnClickListener learnMoreClickListener = (v) -> {
mContext.startActivityForResult(KEY, learnMoreIntent, 0, null);
};
((FooterPreference) preference).setLearnMoreAction(learnMoreClickListener);
((FooterPreference) preference).setLearnMoreText(mContext.getString(learnMoreRes));
}
}
public void setUserId(int userId) {

View File

@@ -19,9 +19,11 @@ package com.android.settings.biometrics.face;
import static android.provider.Settings.Secure.FACE_KEYGUARD_ENABLED;
import android.content.Context;
import android.hardware.face.FaceManager;
import android.provider.Settings;
import androidx.annotation.NonNull;
import androidx.preference.Preference;
import com.android.settings.Utils;
import com.android.settings.biometrics.activeunlock.ActiveUnlockStatusUtils;
@@ -32,9 +34,12 @@ public class FaceSettingsKeyguardUnlockPreferenceController extends
private static final int OFF = 0;
private static final int DEFAULT = ON;
private FaceManager mFaceManager;
public FaceSettingsKeyguardUnlockPreferenceController(
@NonNull Context context, @NonNull String key) {
super(context, key);
mFaceManager = Utils.getFaceManagerOrNull(context);
}
@Override
@@ -49,6 +54,20 @@ public class FaceSettingsKeyguardUnlockPreferenceController extends
FACE_KEYGUARD_ENABLED, isChecked ? ON : OFF, getUserId());
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
if (!FaceSettings.isFaceHardwareDetected(mContext)) {
preference.setEnabled(false);
} else if (!mFaceManager.hasEnrolledTemplates(getUserId())) {
preference.setEnabled(false);
} else if (getRestrictingAdmin() != null) {
preference.setEnabled(false);
} else {
preference.setEnabled(true);
}
}
@Override
public int getAvailabilityStatus() {
final ActiveUnlockStatusUtils activeUnlockStatusUtils =

View File

@@ -31,6 +31,7 @@ import android.widget.Button;
import android.widget.Toast;
import android.window.OnBackInvokedCallback;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
@@ -40,6 +41,7 @@ import com.android.settings.SettingsActivity;
import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.flags.Flags;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.widget.LayoutPreference;
@@ -54,10 +56,11 @@ import java.util.List;
* will likely change if multiple enrollments are allowed/supported.
*/
public class FaceSettingsRemoveButtonPreferenceController extends BasePreferenceController
implements View.OnClickListener {
implements View.OnClickListener, Preference.OnPreferenceClickListener {
private static final String TAG = "FaceSettings/Remove";
static final String KEY = "security_settings_face_delete_faces_container";
static final String KEY_1 = "security_settings_face_remove";
public static class ConfirmRemoveDialog extends InstrumentedDialogFragment
implements OnBackInvokedCallback {
@@ -173,7 +176,11 @@ public class FaceSettingsRemoveButtonPreferenceController extends BasePreference
if (remaining == 0) {
final List<Face> faces = mFaceManager.getEnrolledFaces(mUserId);
if (!faces.isEmpty()) {
mButton.setEnabled(true);
if (Flags.biometricsOnboardingEducation()) {
mPreference.setEnabled(true);
} else {
mButton.setEnabled(true);
}
} else {
mRemoving = false;
mListener.onRemoved();
@@ -189,7 +196,11 @@ public class FaceSettingsRemoveButtonPreferenceController extends BasePreference
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
mButton.setEnabled(false);
if (Flags.biometricsOnboardingEducation()) {
mPreference.setEnabled(false);
} else {
mButton.setEnabled(false);
}
final List<Face> faces = mFaceManager.getEnrolledFaces(mUserId);
if (faces.isEmpty()) {
Log.e(TAG, "No faces");
@@ -202,7 +213,11 @@ public class FaceSettingsRemoveButtonPreferenceController extends BasePreference
// Remove the first/only face
mFaceUpdater.remove(faces.get(0), mUserId, mRemovalCallback);
} else {
mButton.setEnabled(true);
if (Flags.biometricsOnboardingEducation()) {
mPreference.setEnabled(true);
} else {
mButton.setEnabled(true);
}
mRemoving = false;
}
@@ -224,7 +239,7 @@ public class FaceSettingsRemoveButtonPreferenceController extends BasePreference
}
public FaceSettingsRemoveButtonPreferenceController(Context context) {
this(context, KEY);
this(context, Flags.biometricsOnboardingEducation() ? KEY_1 : KEY);
}
public void setUserId(int userId) {
@@ -232,19 +247,21 @@ public class FaceSettingsRemoveButtonPreferenceController extends BasePreference
}
@Override
public void updateState(Preference preference) {
public void updateState(@NonNull Preference preference) {
super.updateState(preference);
mPreference = preference;
mButton = ((LayoutPreference) preference)
.findViewById(R.id.security_settings_face_settings_remove_button);
if (!Flags.biometricsOnboardingEducation()) {
mButton = ((LayoutPreference) preference)
.findViewById(R.id.security_settings_face_settings_remove_button);
if (PartnerStyleHelper.shouldApplyPartnerResource(mButton)) {
ButtonStyler.applyPartnerCustomizationPrimaryButtonStyle(mContext, mButton);
if (PartnerStyleHelper.shouldApplyPartnerResource(mButton)) {
ButtonStyler.applyPartnerCustomizationPrimaryButtonStyle(mContext, mButton);
}
mButton.setOnClickListener(this);
}
mButton.setOnClickListener(this);
// If there is already a ConfirmRemoveDialog showing, reset the listener since the
// controller has been recreated.
ConfirmRemoveDialog removeDialog =
@@ -256,10 +273,19 @@ public class FaceSettingsRemoveButtonPreferenceController extends BasePreference
removeDialog.setOnClickListener(mOnConfirmDialogClickListener);
}
if (!FaceSettings.isFaceHardwareDetected(mContext)) {
mButton.setEnabled(false);
final boolean isFaceHardwareDetected = FaceSettings.isFaceHardwareDetected(mContext);
if (Flags.biometricsOnboardingEducation()) {
if (!isFaceHardwareDetected) {
mPreference.setEnabled(false);
} else {
mPreference.setEnabled(!mRemoving);
}
} else {
mButton.setEnabled(!mRemoving);
if (!isFaceHardwareDetected) {
mButton.setEnabled(false);
} else {
mButton.setEnabled(!mRemoving);
}
}
}
@@ -270,22 +296,32 @@ public class FaceSettingsRemoveButtonPreferenceController extends BasePreference
@Override
public String getPreferenceKey() {
return KEY;
return Flags.biometricsOnboardingEducation() ? KEY_1 : KEY;
}
@Override
public void onClick(View v) {
if (v == mButton) {
mMetricsFeatureProvider.logClickedPreference(mPreference, getMetricsCategory());
mRemoving = true;
ConfirmRemoveDialog confirmRemoveDialog =
ConfirmRemoveDialog.newInstance(BiometricUtils.isConvenience(mFaceManager));
confirmRemoveDialog.setOnClickListener(mOnConfirmDialogClickListener);
confirmRemoveDialog.show(mActivity.getSupportFragmentManager(),
ConfirmRemoveDialog.class.getName());
showRemoveDialog();
}
}
@Override
public boolean onPreferenceClick(@NonNull Preference preference) {
showRemoveDialog();
return true;
}
private void showRemoveDialog() {
mMetricsFeatureProvider.logClickedPreference(mPreference, getMetricsCategory());
mRemoving = true;
ConfirmRemoveDialog confirmRemoveDialog =
ConfirmRemoveDialog.newInstance(BiometricUtils.isConvenience(mFaceManager));
confirmRemoveDialog.setOnClickListener(mOnConfirmDialogClickListener);
confirmRemoveDialog.show(mActivity.getSupportFragmentManager(),
ConfirmRemoveDialog.class.getName());
}
public void setListener(Listener listener) {
mListener = listener;
}