Merge "[Biometric Onboarding & Edu] Support ways to use section for Face & FP" into main
This commit is contained in:
@@ -29,6 +29,7 @@ import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.biometrics.BiometricEnrollBase;
|
||||
@@ -76,6 +77,12 @@ public class CombinedBiometricSettings extends BiometricsSettingsBase {
|
||||
if (mActiveUnlockStatusUtils.isAvailable()) {
|
||||
updateUiForActiveUnlock();
|
||||
}
|
||||
if (Flags.biometricsOnboardingEducation()) {
|
||||
final PreferenceCategory category = findPreference(KEY_USE_BIOMETRIC_PREFERENCE);
|
||||
if (category != null) {
|
||||
category.setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUiForActiveUnlock() {
|
||||
|
||||
@@ -47,6 +47,7 @@ import com.android.settings.biometrics.BiometricEnrollBase;
|
||||
import com.android.settings.biometrics.BiometricUtils;
|
||||
import com.android.settings.biometrics.IdentityCheckBiometricErrorDialog;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.settings.password.ConfirmDeviceCredentialActivity;
|
||||
@@ -76,6 +77,8 @@ public class FaceSettings extends DashboardFragment {
|
||||
"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";
|
||||
public static final String SECURITY_SETTINGS_FACE_MANAGE_CATEGORY =
|
||||
"security_settings_face_manage_category";
|
||||
|
||||
@@ -238,6 +241,12 @@ public class FaceSettings extends DashboardFragment {
|
||||
if (savedInstanceState != null) {
|
||||
mToken = savedInstanceState.getByteArray(KEY_TOKEN);
|
||||
}
|
||||
|
||||
if (Flags.biometricsOnboardingEducation()) {
|
||||
final PreferenceCategory category =
|
||||
findPreference(PREF_KEY_USE_FACE_TO_CATEGORY);
|
||||
category.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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 static android.provider.Settings.Secure.FACE_APP_ENABLED;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.biometrics.activeunlock.ActiveUnlockStatusUtils;
|
||||
|
||||
public class FaceSettingsAppsPreferenceController extends
|
||||
FaceSettingsPreferenceController {
|
||||
private static final int ON = 1;
|
||||
private static final int OFF = 0;
|
||||
private static final int DEFAULT = ON;
|
||||
|
||||
private FaceManager mFaceManager;
|
||||
|
||||
public FaceSettingsAppsPreferenceController(@NonNull Context context, @NonNull String key) {
|
||||
super(context, key);
|
||||
mFaceManager = Utils.getFaceManagerOrNull(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
return Settings.Secure.getIntForUser(mContext.getContentResolver(), FACE_APP_ENABLED,
|
||||
DEFAULT, getUserId()) == ON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setChecked(boolean isChecked) {
|
||||
return Settings.Secure.putIntForUser(mContext.getContentResolver(), FACE_APP_ENABLED,
|
||||
isChecked ? ON : OFF, getUserId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
final ActiveUnlockStatusUtils activeUnlockStatusUtils =
|
||||
new ActiveUnlockStatusUtils(mContext);
|
||||
if (!Utils.hasFaceHardware(mContext)
|
||||
&& !activeUnlockStatusUtils.isAvailable()) {
|
||||
return UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
if (mFaceManager == null) {
|
||||
return AVAILABLE_UNSEARCHABLE;
|
||||
}
|
||||
// This preference will be available only if the user has registered face.
|
||||
final boolean hasFaceEnrolledUser = mFaceManager.hasEnrolledTemplates(getUserId());
|
||||
if (hasFaceEnrolledUser) {
|
||||
return AVAILABLE;
|
||||
} else {
|
||||
return AVAILABLE_UNSEARCHABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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 static android.provider.Settings.Secure.FACE_KEYGUARD_ENABLED;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.biometrics.activeunlock.ActiveUnlockStatusUtils;
|
||||
|
||||
public class FaceSettingsKeyguardUnlockPreferenceController extends
|
||||
FaceSettingsPreferenceController {
|
||||
private static final int ON = 1;
|
||||
private static final int OFF = 0;
|
||||
private static final int DEFAULT = ON;
|
||||
|
||||
public FaceSettingsKeyguardUnlockPreferenceController(
|
||||
@NonNull Context context, @NonNull String key) {
|
||||
super(context, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
return Settings.Secure.getIntForUser(mContext.getContentResolver(),
|
||||
FACE_KEYGUARD_ENABLED, DEFAULT, getUserId()) == ON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setChecked(boolean isChecked) {
|
||||
return Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
||||
FACE_KEYGUARD_ENABLED, isChecked ? ON : OFF, getUserId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
final ActiveUnlockStatusUtils activeUnlockStatusUtils =
|
||||
new ActiveUnlockStatusUtils(mContext);
|
||||
if (activeUnlockStatusUtils.isAvailable()) {
|
||||
return getAvailabilityFromRestrictingAdmin();
|
||||
}
|
||||
if (!Utils.hasFaceHardware(mContext)) {
|
||||
return UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
return getAvailabilityFromRestrictingAdmin();
|
||||
}
|
||||
|
||||
private int getAvailabilityFromRestrictingAdmin() {
|
||||
return getRestrictingAdmin() != null ? DISABLED_FOR_USER : AVAILABLE;
|
||||
}
|
||||
}
|
||||
@@ -273,6 +273,8 @@ public class FingerprintSettings extends SubSettings {
|
||||
"security_settings_fingerprint_footer";
|
||||
private static final String KEY_BIOMETRICS_AUTHENTICATION_REQUESTED =
|
||||
"biometrics_authentication_requested";
|
||||
private static final String KEY_BIOMETRICS_USE_FINGERPRINT_TO_CATEGORY =
|
||||
"biometric_settings_use_fingerprint_to";
|
||||
|
||||
private static final int MSG_REFRESH_FINGERPRINT_TEMPLATES = 1000;
|
||||
private static final int MSG_FINGER_AUTH_SUCCESS = 1001;
|
||||
@@ -656,6 +658,9 @@ public class FingerprintSettings extends SubSettings {
|
||||
private PreferenceScreen createPreferenceHierarchy() {
|
||||
PreferenceScreen root = getPreferenceScreen();
|
||||
addFingerprintPreferences(root);
|
||||
if (Flags.biometricsOnboardingEducation()) {
|
||||
setupUseFingerprintToPreferences();
|
||||
}
|
||||
setPreferenceScreen(root);
|
||||
return root;
|
||||
}
|
||||
@@ -685,6 +690,10 @@ public class FingerprintSettings extends SubSettings {
|
||||
if (mFingerprintsEnrolledCategory != null) {
|
||||
mFingerprintsEnrolledCategory.removeAll();
|
||||
}
|
||||
if (Flags.biometricsOnboardingEducation()) {
|
||||
mFingerprintsEnrolledCategory.setTitle(root.getContext().getString(
|
||||
R.string.security_settings_fingerprint_title));
|
||||
}
|
||||
|
||||
String keyToReturn = mIsExpressiveThemeStyle
|
||||
? KEY_FINGERPRINT_ADD_EXPRESSIVE : KEY_FINGERPRINT_ADD;
|
||||
@@ -815,6 +824,26 @@ public class FingerprintSettings extends SubSettings {
|
||||
});
|
||||
}
|
||||
|
||||
private void setupUseFingerprintToPreferences() {
|
||||
final PreferenceCategory category =
|
||||
findPreference(KEY_BIOMETRICS_USE_FINGERPRINT_TO_CATEGORY);
|
||||
category.setVisible(true);
|
||||
|
||||
// Setup use fingerprint to unlock preference
|
||||
final FingerprintSettingsKeyguardUnlockPreferenceController fpUnlockController =
|
||||
use(FingerprintSettingsKeyguardUnlockPreferenceController.class);
|
||||
fpUnlockController.setUserId(mUserId);
|
||||
findPreference(fpUnlockController.getPreferenceKey())
|
||||
.setOnPreferenceChangeListener(fpUnlockController);
|
||||
|
||||
// Setup use fingerprint to verify it's you in apps preference
|
||||
final FingerprintSettingsAppsPreferenceController fingerprintAppController =
|
||||
use(FingerprintSettingsAppsPreferenceController.class);
|
||||
fingerprintAppController.setUserId(mUserId);
|
||||
findPreference(fingerprintAppController.getPreferenceKey())
|
||||
.setOnPreferenceChangeListener(fingerprintAppController);
|
||||
}
|
||||
|
||||
private void updatePreferencesAfterFingerprintRemoved() {
|
||||
updateAddPreference();
|
||||
if (isSfps() || (screenOffUnlockUdfps() && isUltrasnoicUdfps())) {
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.fingerprint;
|
||||
|
||||
import static android.provider.Settings.Secure.FINGERPRINT_APP_ENABLED;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.biometrics.activeunlock.ActiveUnlockStatusUtils;
|
||||
|
||||
public class FingerprintSettingsAppsPreferenceController
|
||||
extends FingerprintSettingsPreferenceController {
|
||||
private static final int ON = 1;
|
||||
private static final int OFF = 0;
|
||||
private static final int DEFAULT = ON;
|
||||
|
||||
private FingerprintManager mFingerprintManager;
|
||||
|
||||
public FingerprintSettingsAppsPreferenceController(
|
||||
@NonNull Context context, @NonNull String key) {
|
||||
super(context, key);
|
||||
mFingerprintManager = Utils.getFingerprintManagerOrNull(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
return Settings.Secure.getIntForUser(mContext.getContentResolver(), FINGERPRINT_APP_ENABLED,
|
||||
DEFAULT, getUserId()) == ON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setChecked(boolean isChecked) {
|
||||
return Settings.Secure.putIntForUser(mContext.getContentResolver(), FINGERPRINT_APP_ENABLED,
|
||||
isChecked ? ON : OFF, getUserId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
final ActiveUnlockStatusUtils activeUnlockStatusUtils =
|
||||
new ActiveUnlockStatusUtils(mContext);
|
||||
if (!Utils.hasFingerprintHardware(mContext)
|
||||
&& !activeUnlockStatusUtils.isAvailable()) {
|
||||
return UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
if (mFingerprintManager == null) {
|
||||
return AVAILABLE_UNSEARCHABLE;
|
||||
}
|
||||
// This preference will be available only if the user has registered fingerprint.
|
||||
final boolean hasFingerprintEnrolledUser =
|
||||
mFingerprintManager.hasEnrolledTemplates(getUserId());
|
||||
if (hasFingerprintEnrolledUser) {
|
||||
return AVAILABLE;
|
||||
} else {
|
||||
return AVAILABLE_UNSEARCHABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.fingerprint;
|
||||
|
||||
import static android.provider.Settings.Secure.FINGERPRINT_KEYGUARD_ENABLED;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.biometrics.activeunlock.ActiveUnlockStatusUtils;
|
||||
|
||||
public class FingerprintSettingsKeyguardUnlockPreferenceController
|
||||
extends FingerprintSettingsPreferenceController {
|
||||
|
||||
private static final int ON = 1;
|
||||
private static final int OFF = 0;
|
||||
private static final int DEFAULT = ON;
|
||||
|
||||
public FingerprintSettingsKeyguardUnlockPreferenceController(
|
||||
@NonNull Context context, @NonNull String key) {
|
||||
super(context, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
return Settings.Secure.getIntForUser(mContext.getContentResolver(),
|
||||
FINGERPRINT_KEYGUARD_ENABLED, DEFAULT, getUserId()) == ON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setChecked(boolean isChecked) {
|
||||
return Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
||||
FINGERPRINT_KEYGUARD_ENABLED, isChecked ? ON : OFF, getUserId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
final ActiveUnlockStatusUtils activeUnlockStatusUtils =
|
||||
new ActiveUnlockStatusUtils(mContext);
|
||||
if (activeUnlockStatusUtils.isAvailable()) {
|
||||
return getAvailabilityFromRestrictingAdmin();
|
||||
}
|
||||
if (!Utils.hasFingerprintHardware(mContext)) {
|
||||
return UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
return getAvailabilityFromRestrictingAdmin();
|
||||
}
|
||||
|
||||
private int getAvailabilityFromRestrictingAdmin() {
|
||||
return getRestrictingAdmin() != null ? DISABLED_FOR_USER : AVAILABLE;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user