Merge changes from topic "biometric_page" into sc-dev am: 3e6e4a1ad5

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/14276566

Change-Id: Ibaf44154eb0f85a16f49556b337de32ca4169021
This commit is contained in:
TreeHugger Robot
2021-04-23 09:11:30 +00:00
committed by Automerger Merge Worker
28 changed files with 1027 additions and 4 deletions

View File

@@ -494,6 +494,22 @@
android:value="com.android.settings.biometrics.fingerprint.FingerprintSettings$FingerprintSettingsFragment" />
</activity>
<activity android:name="Settings$CombinedBiometricSettingsActivity"
android:label="@string/security_settings_biometric_preference_title"
android:theme="@style/Theme.SubSettings"
android:exported="false">
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.biometrics.combination.CombinedBiometricSettings" />
</activity>
<activity android:name="Settings$CombinedBiometricProfileSettingsActivity"
android:label="@string/security_settings_biometric_preference_title"
android:theme="@style/Theme.SubSettings"
android:exported="false">
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.biometrics.combination.CombinedBiometricProfileSettings" />
</activity>
<activity android:name=".bluetooth.DevicePickerActivity"
android:label="@string/device_picker"
android:configChanges="orientation|keyboardHidden|screenSize"

View File

@@ -969,6 +969,22 @@
<!-- Message shown in fingerprint security settings home screen. [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_v2_home_screen">Use your fingerprint to unlock your phone or for authentication, like when you sign in to apps or approve a purchase\n\n<annotation id="url">Learn more</annotation></string>
<!-- Biometric settings --><skip />
<!-- Title shown for menu item that launches biometric settings. [CHAR LIMIT=66] -->
<string name="security_settings_biometric_preference_title">Face &amp; fingerprint unlock</string>
<!-- Message shown in summary field of biometric settings. [CHAR LIMIT=66] -->
<string name="security_settings_biometric_preference_summary">Face and fingerprint</string>
<!-- Introduction shown in face and fingerprint page to introduce the biometric feature. [CHAR LIMIT=NONE]-->
<string name="biometric_settings_intro">When you set up face unlock and fingerprint, your phone will ask for your fingerprint when you wear a mask or are in a dark area.</string>
<!-- Biometric category title - biometric options for unlocking the device. [CHAR LIMIT=50] -->
<string name="biometric_settings_category_ways_to_unlock">Ways to unlock</string>
<!-- Biometric category title - configuration options for using biometric to unlock the device or authenticate in apps. [CHAR LIMIT=50] -->
<string name="biometric_settings_category_ways_to_use">Use face and fingerprint to</string>
<!-- Text shown on a toggle which allows or disallows the device to use biometric for unlocking the device. [CHAR LIMIT=20] -->
<string name="biometric_settings_use_biometric_unlock_phone">Unlocking your phone</string>
<!-- Text shown on a toggle which allows or disallows the device to use biometric for authentication. [CHAR LIMIT=30] -->
<string name="biometric_settings_use_biometric_for_apps">Authentication in apps</string>
<!-- Title of dialog shown when the user tries to skip setting up a screen lock, warning them of potential consequences of not doing so [CHAR LIMIT=30]-->
<string name="lock_screen_intro_skip_title">Skip screen lock?</string>
<!-- Dialog text shown when the user tries to skip setting up a screen lock, warning them of potential consequences of not doing so, including loss of factory reset protection. (tablet) [CHAR LIMIT=NONE] -->
@@ -8062,6 +8078,7 @@
<string name="keywords_backup">backup, back up</string>
<string name="keywords_assist_gesture_launch">gesture</string>
<string name="keywords_face_unlock">face, unlock, auth, sign in</string>
<string name="keywords_biometric_unlock">face, unlock, auth, sign in, fingerprint, biometric</string>
<string name="keywords_imei_info">imei, meid, min, prl version, imei sv</string>
<string name="keywords_sim_status">network, mobile network state, service state, signal strength, mobile network type, roaming, iccid, eid</string>
<string name="keywords_model_and_hardware">serial number, hardware version</string>
@@ -8087,6 +8104,9 @@
<!-- Search keyword for fingerprint settings. [CHAR_LIMIT=NONE]-->
<string name="keywords_fingerprint_settings">fingerprint, add fingerprint</string>
<!-- Search keyword for biometric settings. [CHAR_LIMIT=NONE]-->
<string name="keywords_biometric_settings">face, fingerprint, add fingerprint</string>
<!-- Search keywords for adaptive brightness setting [CHAR LIMIT=NONE]-->
<string name="keywords_display_auto_brightness">dim screen, touchscreen, battery, smart brightness, dynamic brightness, Auto brightness</string>

View File

@@ -55,6 +55,12 @@
android:title="@string/security_settings_face_preference_title"
android:summary="@string/summary_placeholder"
settings:keywords="@string/keywords_face_settings" />
<Preference
android:key="biometric_settings"
android:title="@string/security_settings_biometric_preference_title"
android:summary="@string/summary_placeholder"
settings:keywords="@string/keywords_biometric_settings" />
</PreferenceCategory>
<!-- work profile security section -->
@@ -91,6 +97,11 @@
android:title="@string/security_settings_face_preference_title"
android:summary="@string/summary_placeholder" />
<Preference
android:key="biometric_settings_profile"
android:title="@string/security_settings_biometric_preference_title"
android:summary="@string/summary_placeholder" />
</PreferenceCategory>
<PreferenceCategory

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2021 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/security_settings_biometric_preference_title">
<com.android.settingslib.widget.TopIntroPreference
android:title="@string/biometric_settings_intro" />
<PreferenceCategory
android:key="biometric_ways_to_unlock"
android:title="@string/biometric_settings_category_ways_to_unlock">
<Preference
android:key="biometric_fingerprint_settings"
android:title="@string/security_settings_fingerprint_preference_title"
android:summary="@string/summary_placeholder"
settings:keywords="@string/keywords_fingerprint_settings"
settings:controller="com.android.settings.biometrics.combination.BiometricFingerprintStatusPreferenceController" />
<Preference
android:key="biometric_face_settings"
android:title="@string/security_settings_face_preference_title"
android:summary="@string/summary_placeholder"
settings:keywords="@string/keywords_face_settings"
settings:controller="com.android.settings.biometrics.combination.BiometricFaceStatusPreferenceController" />
</PreferenceCategory>
<PreferenceCategory
android:key="biometric_ways_to_use"
android:title="@string/biometric_settings_category_ways_to_use">
<com.android.settingslib.RestrictedSwitchPreference
android:key="biometric_settings_biometric_keyguard"
android:title="@string/biometric_settings_use_biometric_unlock_phone"
settings:keywords="@string/keywords_biometric_unlock"
settings:controller="com.android.settings.biometrics.combination.BiometricSettingsKeyguardPreferenceController"/>
<SwitchPreference
android:key="biometric_settings_biometric_app"
android:title="@string/biometric_settings_use_biometric_for_apps"
settings:keywords="@string/keywords_biometric_unlock"
settings:controller="com.android.settings.biometrics.combination.BiometricSettingsAppPreferenceController"/>
</PreferenceCategory>
<SwitchPreference
android:key="biometric_setting_lockdown_enabled"
android:title="@string/lockdown_settings_title"
android:summary="@string/lockdown_settings_summary"
settings:controller="com.android.settings.security.LockdownButtonPreferenceController" />
</PreferenceScreen>

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2021 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/security_settings_biometric_preference_title">
<com.android.settingslib.widget.TopIntroPreference
android:title="@string/biometric_settings_intro" />
<PreferenceCategory
android:key="biometric_ways_to_unlock"
android:title="@string/biometric_settings_category_ways_to_unlock">
<Preference
android:key="biometric_fingerprint_settings_profile"
android:title="@string/security_settings_fingerprint_preference_title"
android:summary="@string/summary_placeholder"
settings:keywords="@string/keywords_fingerprint_settings"
settings:controller="com.android.settings.biometrics.combination.BiometricFingerprintProfileStatusPreferenceController" />
<Preference
android:key="biometric_face_settings_profile"
android:title="@string/security_settings_face_preference_title"
android:summary="@string/summary_placeholder"
settings:keywords="@string/keywords_face_settings"
settings:controller="com.android.settings.biometrics.combination.BiometricFaceProfileStatusPreferenceController" />
</PreferenceCategory>
<PreferenceCategory
android:key="biometric_ways_to_use"
android:title="@string/biometric_settings_category_ways_to_use">
<SwitchPreference
android:key="biometric_settings_biometric_app_profile"
android:title="@string/biometric_settings_use_biometric_for_apps"
settings:keywords="@string/keywords_biometric_unlock"
settings:controller="com.android.settings.biometrics.combination.BiometricSettingsAppPreferenceController"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -31,7 +31,8 @@
<PreferenceCategory
android:key="security_settings_face_unlock_category"
android:title="@string/security_settings_face_settings_use_face_category">
android:title="@string/security_settings_face_settings_use_face_category"
settings:controller="com.android.settings.biometrics.face.FaceUnlockCategoryPreferenceController">
<com.android.settingslib.RestrictedSwitchPreference
android:key="security_settings_face_keyguard"
android:title="@string/security_settings_face_settings_use_face_unlock_phone"
@@ -66,6 +67,13 @@
android:summary="@string/security_settings_face_settings_require_confirmation_details"
settings:keywords="@string/keywords_face_unlock"
settings:controller="com.android.settings.biometrics.face.FaceSettingsConfirmPreferenceController"/>
<com.android.settingslib.RestrictedSwitchPreference
android:key="biometric_settings_lockscreen_bypass"
android:title="@string/lockscreen_bypass_title"
android:summary="@string/lockscreen_bypass_summary"
settings:keywords="@string/keywords_lockscreen_bypass"
settings:controller="com.android.settings.biometrics.face.FaceSettingsLockscreenBypassPreferenceController" />
</PreferenceCategory>
<PreferenceCategory

View File

@@ -38,6 +38,8 @@ public class Settings extends SettingsActivity {
public static class CreateShortcutActivity extends SettingsActivity { /* empty */ }
public static class FaceSettingsActivity extends SettingsActivity { /* empty */ }
public static class FingerprintSettingsActivity extends SettingsActivity { /* empty */ }
public static class CombinedBiometricSettingsActivity extends SettingsActivity { /* empty */ }
public static class CombinedBiometricProfileSettingsActivity extends SettingsActivity { /* empty */ }
public static class TetherSettingsActivity extends SettingsActivity {
// TODO(b/147675042): Clean the override up when we enable the new Fragment persistently.
@Override

View File

@@ -841,6 +841,13 @@ public final class Utils extends com.android.settingslib.Utils {
return faceManager != null && faceManager.isHardwareDetected();
}
/**
* Return true if the device supports multiple biometrics authentications.
*/
public static boolean isMultipleBiometricsSupported(Context context) {
return hasFingerprintHardware(context) && hasFaceHardware(context);
}
/**
* Launches an intent which may optionally have a user id defined.
* @param fragment Fragment to use to launch the activity.

View File

@@ -122,6 +122,9 @@ public abstract class BiometricStatusPreferenceController extends BasePreference
final String clazz = hasEnrolledBiometrics() ? getSettingsClassName()
: getEnrollClassName();
intent.setClassName(SETTINGS_PACKAGE_NAME, clazz);
if (!preference.getExtras().isEmpty()) {
intent.putExtras(preference.getExtras());
}
intent.putExtra(Intent.EXTRA_USER_ID, userId);
intent.putExtra(EXTRA_FROM_SETTINGS_SUMMARY, true);
context.startActivity(intent);

View File

@@ -0,0 +1,42 @@
/*
* Copyright (C) 2021 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.combination;
import android.content.Context;
import android.os.UserHandle;
/**
* Preference controller for face settings within the biometrics settings page of work profile,
* that controls the ability to unlock the phone with face authentication.
*/
public class BiometricFaceProfileStatusPreferenceController extends
BiometricFaceStatusPreferenceController {
public BiometricFaceProfileStatusPreferenceController(Context context, String key) {
super(context, key);
}
@Override
protected boolean isUserSupported() {
return mProfileChallengeUserId != UserHandle.USER_NULL
&& mLockPatternUtils.isSeparateProfileChallengeAllowed(mProfileChallengeUserId);
}
@Override
protected int getUserId() {
return mProfileChallengeUserId;
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2021 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.combination;
import android.content.Context;
import com.android.settings.Utils;
import com.android.settings.biometrics.face.FaceStatusPreferenceController;
/**
* Preference controller for face settings within the biometrics settings page, that controls the
* ability to unlock the phone with face authentication.
*/
public class BiometricFaceStatusPreferenceController extends FaceStatusPreferenceController {
public BiometricFaceStatusPreferenceController(Context context, String key) {
super(context, key);
}
@Override
protected boolean isDeviceSupported() {
return Utils.hasFaceHardware(mContext);
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (C) 2021 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.combination;
import android.content.Context;
import android.os.UserHandle;
/**
* Preference controller for fingerprint settings within the biometrics settings page, that controls
* the ability to unlock the phone with fingerprint.
*/
public class BiometricFingerprintProfileStatusPreferenceController extends
BiometricFingerprintStatusPreferenceController {
public BiometricFingerprintProfileStatusPreferenceController(Context context, String key) {
super(context, key);
}
@Override
protected boolean isUserSupported() {
return mProfileChallengeUserId != UserHandle.USER_NULL
&& mLockPatternUtils.isSeparateProfileChallengeAllowed(mProfileChallengeUserId);
}
@Override
protected int getUserId() {
return mProfileChallengeUserId;
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2021 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.combination;
import android.content.Context;
import com.android.settings.Utils;
import com.android.settings.biometrics.fingerprint.FingerprintStatusPreferenceController;
/**
* Preference controller for fingerprint settings within the biometrics settings page of work
* profile, that controls the ability to unlock the phone with fingerprint.
*/
public class BiometricFingerprintStatusPreferenceController extends
FingerprintStatusPreferenceController {
public BiometricFingerprintStatusPreferenceController(Context context, String key) {
super(context, key);
}
@Override
protected boolean isDeviceSupported() {
return Utils.hasFingerprintHardware(mContext);
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (C) 2021 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.combination;
import static android.provider.Settings.Secure.BIOMETRIC_APP_ENABLED;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.provider.Settings;
import com.android.settings.Utils;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedLockUtilsInternal;
/**
* Preference controller that controls whether the biometrics authentication to be used in apps.
*/
public class BiometricSettingsAppPreferenceController extends TogglePreferenceController {
private static final int ON = 1;
private static final int OFF = 0;
private static final int DEFAULT = ON;
private int mUserId;
private FaceManager mFaceManager;
private FingerprintManager mFingerprintManager;
public BiometricSettingsAppPreferenceController(Context context, String key) {
super(context, key);
mFaceManager = Utils.getFaceManagerOrNull(context);
mFingerprintManager = Utils.getFingerprintManagerOrNull(context);
}
protected EnforcedAdmin getRestrictingAdmin() {
return RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(mContext,
DevicePolicyManager.KEYGUARD_DISABLE_BIOMETRICS, mUserId);
}
public void setUserId(int userId) {
mUserId = userId;
}
@Override
public boolean isChecked() {
return Settings.Secure.getIntForUser(mContext.getContentResolver(), BIOMETRIC_APP_ENABLED,
DEFAULT, mUserId) == ON;
}
@Override
public boolean setChecked(boolean isChecked) {
return Settings.Secure.putIntForUser(mContext.getContentResolver(), BIOMETRIC_APP_ENABLED,
isChecked ? ON : OFF, mUserId);
}
@Override
public int getAvailabilityStatus() {
if (mFaceManager == null || mFingerprintManager == null) {
return AVAILABLE_UNSEARCHABLE;
}
// This preference will be available only if the user has registered either face auth
// or fingerprint.
final boolean hasFaceEnrolledUser = mFaceManager.hasEnrolledTemplates(mUserId);
final boolean hasFingerprintEnrolledUser =
mFingerprintManager.hasEnrolledTemplates(mUserId);
if (hasFaceEnrolledUser || hasFingerprintEnrolledUser) {
return AVAILABLE;
} else {
return AVAILABLE_UNSEARCHABLE;
}
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2021 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.combination;
import static android.provider.Settings.Secure.BIOMETRIC_KEYGUARD_ENABLED;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.provider.Settings;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
/**
* Preference controller that controls whether the biometrics authentication to unlock the device.
*/
public class BiometricSettingsKeyguardPreferenceController extends TogglePreferenceController {
private static final int ON = 1;
private static final int OFF = 0;
private static final int DEFAULT = ON;
private int mUserId;
public BiometricSettingsKeyguardPreferenceController(Context context, String key) {
super(context, key);
}
protected RestrictedLockUtils.EnforcedAdmin getRestrictingAdmin() {
return RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(mContext,
DevicePolicyManager.KEYGUARD_DISABLE_BIOMETRICS, mUserId);
}
public void setUserId(int userId) {
mUserId = userId;
}
@Override
public boolean isChecked() {
return Settings.Secure.getIntForUser(mContext.getContentResolver(),
BIOMETRIC_KEYGUARD_ENABLED, DEFAULT, mUserId) == ON;
}
@Override
public boolean setChecked(boolean isChecked) {
return Settings.Secure.putIntForUser(mContext.getContentResolver(),
BIOMETRIC_KEYGUARD_ENABLED, isChecked ? ON : OFF, mUserId);
}
@Override
public int getAvailabilityStatus() {
return getRestrictingAdmin() != null ? DISABLED_FOR_USER : AVAILABLE;
}
}

View File

@@ -0,0 +1,197 @@
/*
* Copyright (C) 2021 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.combination;
import static android.app.Activity.RESULT_OK;
import static com.android.settings.password.ChooseLockPattern.RESULT_FINISHED;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.os.UserHandle;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.password.ChooseLockSettingsHelper;
/**
* Base fragment with the confirming credential functionality for combined biometrics settings.
*/
public abstract class BiometricsSettingsBase extends DashboardFragment {
private static final int CONFIRM_REQUEST = 2001;
private static final int CHOOSE_LOCK_REQUEST = 2002;
private static final String SAVE_STATE_CONFIRM_CREDETIAL = "confirm_credential";
protected int mUserId;
protected long mFaceChallenge;
protected long mFingerprintChallenge;
protected int mFaceSensorId;
protected int mFingerprintSensorId;
protected long mGkPwHandle;
private boolean mConfirmCredential;
@Nullable private FaceManager mFaceManager;
@Nullable private FingerprintManager mFingerprintManager;
@Override
public void onAttach(Context context) {
super.onAttach(context);
mUserId = getActivity().getIntent().getIntExtra(Intent.EXTRA_USER_ID,
UserHandle.myUserId());
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFaceManager = Utils.getFaceManagerOrNull(getActivity());
mFingerprintManager = Utils.getFingerprintManagerOrNull(getActivity());
if (BiometricUtils.containsGatekeeperPasswordHandle(getIntent())) {
mGkPwHandle = BiometricUtils.getGatekeeperPasswordHandle(getIntent());
}
if (savedInstanceState != null) {
mConfirmCredential = savedInstanceState.getBoolean(SAVE_STATE_CONFIRM_CREDETIAL);
if (savedInstanceState.containsKey(
ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE)) {
mGkPwHandle = savedInstanceState.getLong(
ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE);
}
}
if (mGkPwHandle == 0L && !mConfirmCredential) {
mConfirmCredential = true;
launchChooseOrConfirmLock();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (getActivity().isFinishing()) {
mFaceManager.revokeChallenge(mFaceSensorId, mUserId, mFaceChallenge);
mFingerprintManager.revokeChallenge(mUserId, mFingerprintChallenge);
BiometricUtils.removeGatekeeperPasswordHandle(getActivity(), mGkPwHandle);
}
}
@Override
public boolean onPreferenceTreeClick(Preference preference) {
final String key = preference.getKey();
if (getFacePreferenceKey().equals(key)) {
final byte[] token = BiometricUtils.requestGatekeeperHat(getActivity(), mGkPwHandle,
mUserId, mFaceChallenge);
final Bundle extras = preference.getExtras();
extras.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
extras.putInt(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, mFaceSensorId);
extras.putLong(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, mFaceChallenge);
} else if (getFingerprintPreferenceKey().equals(key)) {
final byte[] token = BiometricUtils.requestGatekeeperHat(getActivity(), mGkPwHandle,
mUserId, mFingerprintChallenge);
final Bundle extras = preference.getExtras();
extras.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
extras.putLong(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, mFingerprintChallenge);
}
return super.onPreferenceTreeClick(preference);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(SAVE_STATE_CONFIRM_CREDETIAL, mConfirmCredential);
if (mGkPwHandle != 0L) {
outState.putLong(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, mGkPwHandle);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CONFIRM_REQUEST || requestCode == CHOOSE_LOCK_REQUEST) {
mConfirmCredential = false;
if (resultCode == RESULT_FINISHED || resultCode == RESULT_OK) {
if (data != null && BiometricUtils.containsGatekeeperPasswordHandle(data)) {
mGkPwHandle = BiometricUtils.getGatekeeperPasswordHandle(data);
mFaceManager.generateChallenge((sensorId, challenge) -> {
mFaceSensorId = sensorId;
mFaceChallenge = challenge;
});
mFingerprintManager.generateChallenge(mUserId, (sensorId, challenge) -> {
mFingerprintSensorId = sensorId;
mFingerprintChallenge = challenge;
});
} else {
Log.d(getLogTag(), "Data null or GK PW missing.");
finish();
}
} else {
Log.d(getLogTag(), "Password not confirmed.");
finish();
}
}
}
/**
* Get the preference key of face for passing through credential data to face settings.
*/
public abstract String getFacePreferenceKey();
/**
* Get the preference key of face for passing through credential data to face settings.
*/
public abstract String getFingerprintPreferenceKey();
private void launchChooseOrConfirmLock() {
final ChooseLockSettingsHelper.Builder builder =
new ChooseLockSettingsHelper.Builder(getActivity(), this)
.setRequestCode(CONFIRM_REQUEST)
.setTitle(getString(R.string.security_settings_biometric_preference_title))
.setRequestGatekeeperPasswordHandle(true)
.setForegroundOnly(true)
.setReturnCredentials(true);
if (mUserId != UserHandle.USER_NULL) {
builder.setUserId(mUserId);
}
final boolean launched = builder.show();
if (!launched) {
Intent intent = BiometricUtils.getChooseLockIntent(getActivity(), getIntent());
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, true);
if (mUserId != UserHandle.USER_NULL) {
intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
}
startActivityForResult(intent, CHOOSE_LOCK_REQUEST);
}
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2021 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.combination;
import android.app.settings.SettingsEnums;
import android.content.Context;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
/**
* Settings screen for multiple biometrics used in work profile.
*/
public class CombinedBiometricProfileSettings extends BiometricsSettingsBase {
private static final String TAG = "BiometricProfileSetting";
private static final String KEY_FACE_SETTINGS = "biometric_face_settings_profile";
private static final String KEY_FINGERPRINT_SETTINGS = "biometric_fingerprint_settings_profile";
@Override
public void onAttach(Context context) {
super.onAttach(context);
use(BiometricSettingsAppPreferenceController.class).setUserId(mUserId);
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.security_settings_combined_biometric_profile;
}
@Override
public String getFacePreferenceKey() {
return KEY_FACE_SETTINGS;
}
@Override
public String getFingerprintPreferenceKey() {
return KEY_FINGERPRINT_SETTINGS;
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
public int getMetricsCategory() {
return SettingsEnums.COMBINED_BIOMETRIC_PROFILE;
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.security_settings_combined_biometric_profile);
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (C) 2021 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.combination;
import android.content.Context;
import android.os.UserHandle;
import com.android.settings.Settings;
/**
* Preference controller for biometrics settings page of work profile, controlling the ability to
* unlock the phone with face and fingerprint.
*/
public class CombinedBiometricProfileStatusPreferenceController extends
CombinedBiometricStatusPreferenceController {
private static final String KEY_BIOMETRIC_SETTINGS = "biometric_settings_profile";
public CombinedBiometricProfileStatusPreferenceController(Context context) {
super(context, KEY_BIOMETRIC_SETTINGS);
}
public CombinedBiometricProfileStatusPreferenceController(Context context, String key) {
super(context, key);
}
@Override
protected boolean isUserSupported() {
return mProfileChallengeUserId != UserHandle.USER_NULL
&& mLockPatternUtils.isSeparateProfileChallengeAllowed(mProfileChallengeUserId);
}
@Override
protected int getUserId() {
return mProfileChallengeUserId;
}
@Override
protected String getSettingsClassName() {
return Settings.CombinedBiometricProfileSettingsActivity.class.getName();
}
@Override
protected String getEnrollClassName() {
return Settings.CombinedBiometricProfileSettingsActivity.class.getName();
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2021 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.combination;
import android.app.settings.SettingsEnums;
import android.content.Context;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable;
/**
* Settings screen for multiple biometrics.
*/
@SearchIndexable
public class CombinedBiometricSettings extends BiometricsSettingsBase {
private static final String TAG = "BiometricSettings";
private static final String KEY_FACE_SETTINGS = "biometric_face_settings";
private static final String KEY_FINGERPRINT_SETTINGS = "biometric_fingerprint_settings";
@Override
public void onAttach(Context context) {
super.onAttach(context);
use(BiometricSettingsKeyguardPreferenceController.class).setUserId(mUserId);
use(BiometricSettingsAppPreferenceController.class).setUserId(mUserId);
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.security_settings_combined_biometric;
}
@Override
public String getFacePreferenceKey() {
return KEY_FACE_SETTINGS;
}
@Override
public String getFingerprintPreferenceKey() {
return KEY_FINGERPRINT_SETTINGS;
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
public int getMetricsCategory() {
return SettingsEnums.COMBINED_BIOMETRIC;
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.security_settings_combined_biometric);
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2021 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.combination;
import android.content.Context;
import com.android.settings.R;
import com.android.settings.Settings;
import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricStatusPreferenceController;
/**
* Preference controller for biometrics settings page controlling the ability to unlock the phone
* with face and fingerprint.
*/
public class CombinedBiometricStatusPreferenceController extends
BiometricStatusPreferenceController {
private static final String KEY_BIOMETRIC_SETTINGS = "biometric_settings";
public CombinedBiometricStatusPreferenceController(Context context) {
this(context, KEY_BIOMETRIC_SETTINGS);
}
public CombinedBiometricStatusPreferenceController(Context context, String key) {
super(context, key);
}
@Override
protected boolean isDeviceSupported() {
return Utils.hasFingerprintHardware(mContext) && Utils.hasFaceHardware(mContext);
}
@Override
protected boolean hasEnrolledBiometrics() {
return false;
}
@Override
protected String getSummaryTextEnrolled() {
return mContext.getString(R.string.security_settings_biometric_preference_summary);
}
@Override
protected String getSummaryTextNoneEnrolled() {
return mContext.getString(R.string.security_settings_biometric_preference_summary);
}
@Override
protected String getSettingsClassName() {
return Settings.CombinedBiometricSettingsActivity.class.getName();
}
@Override
protected String getEnrollClassName() {
return Settings.CombinedBiometricSettingsActivity.class.getName();
}
}

View File

@@ -78,6 +78,11 @@ public class FaceSettingsAppPreferenceController extends FaceSettingsPreferenceC
@Override
public int getAvailabilityStatus() {
// When the device supports multiple biometrics auth, this preference will be hidden.
if (Utils.isMultipleBiometricsSupported(mContext)) {
return UNSUPPORTED_ON_DEVICE;
}
if(mFaceManager == null){
return AVAILABLE_UNSEARCHABLE;
}

View File

@@ -70,7 +70,8 @@ public class FaceSettingsKeyguardPreferenceController extends FaceSettingsPrefer
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
// When the device supports multiple biometrics auth, this preference will be unavailable.
return Utils.isMultipleBiometricsSupported(mContext) ? UNSUPPORTED_ON_DEVICE : AVAILABLE;
}
@Override

View File

@@ -26,6 +26,7 @@ import android.provider.Settings;
import androidx.preference.Preference;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.Utils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedSwitchPreference;
@@ -82,6 +83,11 @@ public class FaceSettingsLockscreenBypassPreferenceController
@Override
public int getAvailabilityStatus() {
// When the device supports multiple biometrics auth, this preference will be shown
// in face unlock category.
if (Utils.isMultipleBiometricsSupported(mContext)) {
return AVAILABLE;
}
if (mUserManager.isManagedProfile(UserHandle.myUserId())) {
return UNSUPPORTED_ON_DEVICE;
}

View File

@@ -41,7 +41,7 @@ public class FaceStatusPreferenceController extends BiometricStatusPreferenceCon
@Override
protected boolean isDeviceSupported() {
return FaceSettings.isFaceHardwareDetected(mContext);
return !Utils.isMultipleBiometricsSupported(mContext) && Utils.hasFaceHardware(mContext);
}
@Override

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2021 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 com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController;
/**
* Preference controller that controls the face unlock features to be shown / be hidden.
*/
public class FaceUnlockCategoryPreferenceController extends BasePreferenceController {
public FaceUnlockCategoryPreferenceController(Context context, String key) {
super(context, key);
}
@Override
public int getAvailabilityStatus() {
return Utils.isMultipleBiometricsSupported(mContext) ? UNSUPPORTED_ON_DEVICE : AVAILABLE;
}
}

View File

@@ -40,7 +40,8 @@ public class FingerprintStatusPreferenceController extends BiometricStatusPrefer
@Override
protected boolean isDeviceSupported() {
return mFingerprintManager != null && mFingerprintManager.isHardwareDetected();
return !Utils.isMultipleBiometricsSupported(mContext)
&& Utils.hasFingerprintHardware(mContext);
}
@Override

View File

@@ -63,6 +63,8 @@ import com.android.settings.applications.specialaccess.zenaccess.ZenAccessDetail
import com.android.settings.backup.PrivacySettings;
import com.android.settings.backup.ToggleBackupSettingFragment;
import com.android.settings.backup.UserBackupSettingsActivity;
import com.android.settings.biometrics.combination.CombinedBiometricProfileSettings;
import com.android.settings.biometrics.combination.CombinedBiometricSettings;
import com.android.settings.biometrics.face.FaceSettings;
import com.android.settings.biometrics.fingerprint.FingerprintSettings;
import com.android.settings.bluetooth.BluetoothDeviceDetailsFragment;
@@ -222,6 +224,8 @@ public class SettingsGateway {
AssistGestureSettings.class.getName(),
FaceSettings.class.getName(),
FingerprintSettings.FingerprintSettingsFragment.class.getName(),
CombinedBiometricSettings.class.getName(),
CombinedBiometricProfileSettings.class.getName(),
SwipeToNotificationSettings.class.getName(),
DoubleTapPowerSettings.class.getName(),
DoubleTapScreenSettings.class.getName(),

View File

@@ -22,6 +22,8 @@ import android.content.Context;
import android.content.Intent;
import com.android.settings.R;
import com.android.settings.biometrics.combination.CombinedBiometricProfileStatusPreferenceController;
import com.android.settings.biometrics.combination.CombinedBiometricStatusPreferenceController;
import com.android.settings.biometrics.face.FaceProfileStatusPreferenceController;
import com.android.settings.biometrics.face.FaceStatusPreferenceController;
import com.android.settings.biometrics.fingerprint.FingerprintProfileStatusPreferenceController;
@@ -115,6 +117,7 @@ public class SecuritySettings extends DashboardFragment {
final List<AbstractPreferenceController> securityPreferenceControllers = new ArrayList<>();
securityPreferenceControllers.add(new FaceStatusPreferenceController(context));
securityPreferenceControllers.add(new FingerprintStatusPreferenceController(context));
securityPreferenceControllers.add(new CombinedBiometricStatusPreferenceController(context));
securityPreferenceControllers.add(new ChangeScreenLockPreferenceController(context, host));
controllers.add(new PreferenceCategoryController(context, SECURITY_CATEGORY)
.setChildren(securityPreferenceControllers));
@@ -128,6 +131,8 @@ public class SecuritySettings extends DashboardFragment {
context, lifecycle));
profileSecurityControllers.add(new FaceProfileStatusPreferenceController(context));
profileSecurityControllers.add(new FingerprintProfileStatusPreferenceController(context));
profileSecurityControllers
.add(new CombinedBiometricProfileStatusPreferenceController(context));
controllers.add(new PreferenceCategoryController(context, WORK_PROFILE_SECURITY_CATEGORY)
.setChildren(profileSecurityControllers));
controllers.addAll(profileSecurityControllers);