diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c352694f9f5..9b11fe81c98 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -494,6 +494,22 @@ android:value="com.android.settings.biometrics.fingerprint.FingerprintSettings$FingerprintSettingsFragment" /> + + + + + + + + Use your fingerprint to unlock your phone or for authentication, like when you sign in to apps or approve a purchase\n\nLearn more + + + Face & fingerprint unlock + + Face and fingerprint + + 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. + + Ways to unlock + + Use face and fingerprint to + + Unlocking your phone + + Authentication in apps + Skip screen lock? @@ -8062,6 +8078,7 @@ backup, back up gesture face, unlock, auth, sign in + face, unlock, auth, sign in, fingerprint, biometric imei, meid, min, prl version, imei sv network, mobile network state, service state, signal strength, mobile network type, roaming, iccid, eid serial number, hardware version @@ -8087,6 +8104,9 @@ fingerprint, add fingerprint + + face, fingerprint, add fingerprint + dim screen, touchscreen, battery, smart brightness, dynamic brightness, Auto brightness diff --git a/res/xml/security_dashboard_settings.xml b/res/xml/security_dashboard_settings.xml index fd9f3186996..be1f34cebe3 100644 --- a/res/xml/security_dashboard_settings.xml +++ b/res/xml/security_dashboard_settings.xml @@ -55,6 +55,12 @@ android:title="@string/security_settings_face_preference_title" android:summary="@string/summary_placeholder" settings:keywords="@string/keywords_face_settings" /> + + @@ -91,6 +97,11 @@ android:title="@string/security_settings_face_preference_title" android:summary="@string/summary_placeholder" /> + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/xml/security_settings_combined_biometric_profile.xml b/res/xml/security_settings_combined_biometric_profile.xml new file mode 100644 index 00000000000..57111528603 --- /dev/null +++ b/res/xml/security_settings_combined_biometric_profile.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/xml/security_settings_face.xml b/res/xml/security_settings_face.xml index 1fc1ca82de5..131f222685c 100644 --- a/res/xml/security_settings_face.xml +++ b/res/xml/security_settings_face.xml @@ -31,7 +31,8 @@ + android:title="@string/security_settings_face_settings_use_face_category" + settings:controller="com.android.settings.biometrics.face.FaceUnlockCategoryPreferenceController"> + + { + 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); + } + } +} diff --git a/src/com/android/settings/biometrics/combination/CombinedBiometricProfileSettings.java b/src/com/android/settings/biometrics/combination/CombinedBiometricProfileSettings.java new file mode 100644 index 00000000000..08c934dbc44 --- /dev/null +++ b/src/com/android/settings/biometrics/combination/CombinedBiometricProfileSettings.java @@ -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); +} diff --git a/src/com/android/settings/biometrics/combination/CombinedBiometricProfileStatusPreferenceController.java b/src/com/android/settings/biometrics/combination/CombinedBiometricProfileStatusPreferenceController.java new file mode 100644 index 00000000000..e9cbcd8e763 --- /dev/null +++ b/src/com/android/settings/biometrics/combination/CombinedBiometricProfileStatusPreferenceController.java @@ -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(); + } +} diff --git a/src/com/android/settings/biometrics/combination/CombinedBiometricSettings.java b/src/com/android/settings/biometrics/combination/CombinedBiometricSettings.java new file mode 100644 index 00000000000..9ebb62f4939 --- /dev/null +++ b/src/com/android/settings/biometrics/combination/CombinedBiometricSettings.java @@ -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); +} diff --git a/src/com/android/settings/biometrics/combination/CombinedBiometricStatusPreferenceController.java b/src/com/android/settings/biometrics/combination/CombinedBiometricStatusPreferenceController.java new file mode 100644 index 00000000000..c3db1742755 --- /dev/null +++ b/src/com/android/settings/biometrics/combination/CombinedBiometricStatusPreferenceController.java @@ -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(); + } +} diff --git a/src/com/android/settings/biometrics/face/FaceSettingsAppPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsAppPreferenceController.java index bde146b19cd..c296e56aa08 100644 --- a/src/com/android/settings/biometrics/face/FaceSettingsAppPreferenceController.java +++ b/src/com/android/settings/biometrics/face/FaceSettingsAppPreferenceController.java @@ -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; } diff --git a/src/com/android/settings/biometrics/face/FaceSettingsKeyguardPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsKeyguardPreferenceController.java index 8ee7ffd57ce..342d7864829 100644 --- a/src/com/android/settings/biometrics/face/FaceSettingsKeyguardPreferenceController.java +++ b/src/com/android/settings/biometrics/face/FaceSettingsKeyguardPreferenceController.java @@ -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 diff --git a/src/com/android/settings/biometrics/face/FaceSettingsLockscreenBypassPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsLockscreenBypassPreferenceController.java index 0a2757b5cbd..2f0ef4f1238 100644 --- a/src/com/android/settings/biometrics/face/FaceSettingsLockscreenBypassPreferenceController.java +++ b/src/com/android/settings/biometrics/face/FaceSettingsLockscreenBypassPreferenceController.java @@ -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; } diff --git a/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java b/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java index 94651d754ac..c2143c043e0 100644 --- a/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java +++ b/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java @@ -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 diff --git a/src/com/android/settings/biometrics/face/FaceUnlockCategoryPreferenceController.java b/src/com/android/settings/biometrics/face/FaceUnlockCategoryPreferenceController.java new file mode 100644 index 00000000000..d0debdfe594 --- /dev/null +++ b/src/com/android/settings/biometrics/face/FaceUnlockCategoryPreferenceController.java @@ -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; + } +} diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintStatusPreferenceController.java b/src/com/android/settings/biometrics/fingerprint/FingerprintStatusPreferenceController.java index 0e1ccd7839a..e53dbc411a1 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintStatusPreferenceController.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintStatusPreferenceController.java @@ -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 diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java index a6305cbb83a..01c613a6c0c 100644 --- a/src/com/android/settings/core/gateway/SettingsGateway.java +++ b/src/com/android/settings/core/gateway/SettingsGateway.java @@ -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(), diff --git a/src/com/android/settings/security/SecuritySettings.java b/src/com/android/settings/security/SecuritySettings.java index 577144fedc0..01cdba7b3ca 100644 --- a/src/com/android/settings/security/SecuritySettings.java +++ b/src/com/android/settings/security/SecuritySettings.java @@ -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 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);