For private space lock setup as part of both PS setup and separate lock form private space settings we need to show only traditional unlock factors and Fingerprint but not show Face enrolment even on devices where Face unlock is supported by hardware. Once LSKF is enrolled it should be followed by Fingerprint enrollment flow and after that Face enrollment should not be shown and exit lock setup flow. Currently for separate profile lock setup ACTION_SET_NEW_PASSWORD intent is used in private space setup. With this intent the options of LSKF+fingerprint+Face is shown in devices supporting both fingerprint and face hardware. After the LSKF ennrollment BiometricEnrollActivity is started which continues with fingerprint and Face enrollment. With this change we are passing an extra along with the intent to enroll fingerprint only. Based on the intent extra value if set even if hardware support exists the lock enrollment for the profile will support only LSKF and fingerprint enrollment but not start Face enrollment. User will still have the option to enroll Face from the dedicated settings entrypoint in private space settings. Recording link : b/323839067#comment4 Bug: 323839067 Test: Manual, verified option for face enrollment is shown or not shown based on the intent extra. When extra is not passed the behaviour will be default. Change-Id: Idf92084052e02df9ca89f288c618796750e563e6
185 lines
7.7 KiB
Java
185 lines
7.7 KiB
Java
/*
|
|
* Copyright (C) 2016 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.password;
|
|
|
|
import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD;
|
|
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FACE;
|
|
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT;
|
|
|
|
import static com.android.internal.util.Preconditions.checkNotNull;
|
|
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FINGERPRINT_ENROLLMENT_ONLY;
|
|
|
|
import android.app.ActivityManager;
|
|
import android.app.admin.DevicePolicyManager;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.pm.PackageManager;
|
|
import android.hardware.face.FaceManager;
|
|
import android.hardware.fingerprint.FingerprintManager;
|
|
import android.os.Bundle;
|
|
import android.os.IBinder;
|
|
import android.os.UserManager;
|
|
|
|
import androidx.annotation.Nullable;
|
|
import androidx.annotation.VisibleForTesting;
|
|
|
|
import com.android.settings.Utils;
|
|
|
|
/**
|
|
* Business logic for {@link SetNewPasswordActivity}.
|
|
*
|
|
* <p>On devices that supports fingerprint, this controller directs the user to configure
|
|
* fingerprint + a backup password if the device admin allows fingerprint for keyguard and
|
|
* the user has never configured a fingerprint before.
|
|
*/
|
|
final class SetNewPasswordController {
|
|
|
|
interface Ui {
|
|
/** Starts the {@link ChooseLockGeneric} activity with the given extras. */
|
|
void launchChooseLock(Bundle chooseLockFingerprintExtras);
|
|
}
|
|
|
|
/**
|
|
* Which user is setting new password.
|
|
*/
|
|
private final int mTargetUserId;
|
|
private final PackageManager mPackageManager;
|
|
@Nullable
|
|
private final FingerprintManager mFingerprintManager;
|
|
@Nullable
|
|
private final FaceManager mFaceManager;
|
|
private final DevicePolicyManager mDevicePolicyManager;
|
|
private final Ui mUi;
|
|
|
|
public static SetNewPasswordController create(Context context, Ui ui, Intent intent,
|
|
IBinder activityToken) {
|
|
// Trying to figure out which user is setting new password. If it is
|
|
// ACTION_SET_NEW_PARENT_PROFILE_PASSWORD, it is the current user to set
|
|
// new password. Otherwise, it is the user who starts this activity
|
|
// setting new password.
|
|
final int userId;
|
|
if (ACTION_SET_NEW_PASSWORD.equals(intent.getAction())) {
|
|
userId = Utils.getSecureTargetUser(activityToken,
|
|
UserManager.get(context), null, intent.getExtras()).getIdentifier();
|
|
} else {
|
|
userId = ActivityManager.getCurrentUser();
|
|
}
|
|
// Create a wrapper of FingerprintManager for testing, see IFingerPrintManager for details.
|
|
final FingerprintManager fingerprintManager = Utils.getFingerprintManagerOrNull(context);
|
|
final FaceManager faceManager =
|
|
!intent.getBooleanExtra(EXTRA_KEY_FINGERPRINT_ENROLLMENT_ONLY, false)
|
|
? Utils.getFaceManagerOrNull(context)
|
|
: null;
|
|
return new SetNewPasswordController(userId,
|
|
context.getPackageManager(),
|
|
fingerprintManager, faceManager,
|
|
(DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE), ui);
|
|
}
|
|
|
|
@VisibleForTesting
|
|
SetNewPasswordController(
|
|
int targetUserId,
|
|
PackageManager packageManager,
|
|
FingerprintManager fingerprintManager,
|
|
FaceManager faceManager,
|
|
DevicePolicyManager devicePolicyManager,
|
|
Ui ui) {
|
|
mTargetUserId = targetUserId;
|
|
mPackageManager = checkNotNull(packageManager);
|
|
mFingerprintManager = fingerprintManager;
|
|
mFaceManager = faceManager;
|
|
mDevicePolicyManager = checkNotNull(devicePolicyManager);
|
|
mUi = checkNotNull(ui);
|
|
}
|
|
|
|
/**
|
|
* Dispatches the set new password intent to the correct activity that handles it.
|
|
*/
|
|
public void dispatchSetNewPasswordIntent() {
|
|
final Bundle extras;
|
|
|
|
final boolean hasFeatureFingerprint = mPackageManager
|
|
.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT);
|
|
final boolean hasFeatureFace = mPackageManager
|
|
.hasSystemFeature(PackageManager.FEATURE_FACE);
|
|
|
|
final boolean shouldShowFingerprintEnroll = mFingerprintManager != null
|
|
&& mFingerprintManager.isHardwareDetected()
|
|
&& !mFingerprintManager.hasEnrolledFingerprints(mTargetUserId)
|
|
&& !isFingerprintDisabledByAdmin();
|
|
final boolean shouldShowFaceEnroll = mFaceManager != null
|
|
&& mFaceManager.isHardwareDetected()
|
|
&& !mFaceManager.hasEnrolledTemplates(mTargetUserId)
|
|
&& !isFaceDisabledByAdmin();
|
|
|
|
if (hasFeatureFace && shouldShowFaceEnroll
|
|
&& hasFeatureFingerprint && shouldShowFingerprintEnroll) {
|
|
extras = getBiometricChooseLockExtras();
|
|
} else if (hasFeatureFace && shouldShowFaceEnroll) {
|
|
extras = getFaceChooseLockExtras();
|
|
} else if (hasFeatureFingerprint && shouldShowFingerprintEnroll) {
|
|
extras = getFingerprintChooseLockExtras();
|
|
} else {
|
|
extras = new Bundle();
|
|
}
|
|
|
|
// No matter we show fingerprint options or not, we should tell the next activity which
|
|
// user is setting new password.
|
|
extras.putInt(Intent.EXTRA_USER_ID, mTargetUserId);
|
|
mUi.launchChooseLock(extras);
|
|
}
|
|
|
|
private Bundle getBiometricChooseLockExtras() {
|
|
Bundle chooseLockExtras = new Bundle();
|
|
chooseLockExtras.putBoolean(
|
|
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
|
|
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
|
|
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, true);
|
|
return chooseLockExtras;
|
|
}
|
|
|
|
private Bundle getFingerprintChooseLockExtras() {
|
|
Bundle chooseLockExtras = new Bundle();
|
|
chooseLockExtras.putBoolean(
|
|
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
|
|
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
|
|
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true);
|
|
return chooseLockExtras;
|
|
}
|
|
|
|
private Bundle getFaceChooseLockExtras() {
|
|
Bundle chooseLockExtras = new Bundle();
|
|
chooseLockExtras.putBoolean(
|
|
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
|
|
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
|
|
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, true);
|
|
return chooseLockExtras;
|
|
}
|
|
|
|
private boolean isFingerprintDisabledByAdmin() {
|
|
int disabledFeatures =
|
|
mDevicePolicyManager.getKeyguardDisabledFeatures(null, mTargetUserId);
|
|
return (disabledFeatures & KEYGUARD_DISABLE_FINGERPRINT) != 0;
|
|
}
|
|
|
|
private boolean isFaceDisabledByAdmin() {
|
|
int disabledFeatures =
|
|
mDevicePolicyManager.getKeyguardDisabledFeatures(null, mTargetUserId);
|
|
return (disabledFeatures & KEYGUARD_DISABLE_FACE) != 0;
|
|
}
|
|
}
|