Files
packages_apps_Settings/src/com/android/settings/biometrics/GatekeeperPasswordProvider.java
Milton Wu 160661dc6d Launch settings for clicking fingerprint unlock
Launch FingerprintSettings directly when user clicks "Fingerprint
Unlock". Let Fingerprint settings peform confirmLock() or chooseLock().
And to have smoothly animation, instead of generating challenge in
FingerprintSettings::onActivityResult(), challenge is generated in next
visible activity, and pass it back through next activity result.

Bug: 197717071
Test: atest GatekeeperPasswordProviderTest CredentialModelTest
Test: atest AutoCredentialViewModelTest FingerprintStatusUtilsTest
Test: RunSettingsRoboTests2 FingerprintEnrollIntroductionTest
Test: Manually test fingerprint enroll in settings or suw
Change-Id: Ie27c3c493ea475f6b53cb6bb3f2d45d555f47cb3
2022-12-30 10:01:06 +08:00

129 lines
5.3 KiB
Java

/*
* Copyright (C) 2022 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;
import static com.android.settings.biometrics.BiometricUtils.GatekeeperCredentialNotMatchException;
import android.content.Intent;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.VerifyCredentialResponse;
import com.android.settings.password.ChooseLockSettingsHelper;
/**
* Gatekeeper hat related methods
*/
public class GatekeeperPasswordProvider {
private static final String TAG = "GatekeeperPasswordProvider";
private final LockPatternUtils mLockPatternUtils;
public GatekeeperPasswordProvider(LockPatternUtils lockPatternUtils) {
mLockPatternUtils = lockPatternUtils;
}
/**
* Given the result from confirming or choosing a credential, request Gatekeeper to generate
* a HardwareAuthToken with the Gatekeeper Password together with a biometric challenge.
*
* @param result The onActivityResult intent from ChooseLock* or ConfirmLock*
* @param challenge Unique biometric challenge from FingerprintManager/FaceManager
* @param userId User ID that the credential/biometric operation applies to
* @throws GatekeeperCredentialNotMatchException if Gatekeeper response is not match
* @throws IllegalStateException if Gatekeeper Password is missing
*/
public byte[] requestGatekeeperHat(@NonNull Intent result, long challenge, int userId) {
if (!containsGatekeeperPasswordHandle(result)) {
throw new IllegalStateException("Gatekeeper Password is missing!!");
}
final long gatekeeperPasswordHandle = result.getLongExtra(
ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, 0L);
return requestGatekeeperHat(gatekeeperPasswordHandle, challenge, userId);
}
/**
* Given the result from confirming or choosing a credential, request Gatekeeper to generate
* a HardwareAuthToken with the Gatekeeper Password together with a biometric challenge.
*
* @param gkPwHandle The Gatekeeper password handle from ChooseLock* or ConfirmLock*
* @param challenge Unique biometric challenge from FingerprintManager/FaceManager
* @param userId User ID that the credential/biometric operation applies to
* @throws GatekeeperCredentialNotMatchException if Gatekeeper response is not match
*/
public byte[] requestGatekeeperHat(long gkPwHandle, long challenge, int userId) {
final VerifyCredentialResponse response = mLockPatternUtils.verifyGatekeeperPasswordHandle(
gkPwHandle, challenge, userId);
if (!response.isMatched()) {
throw new GatekeeperCredentialNotMatchException("Unable to request Gatekeeper HAT");
}
return response.getGatekeeperHAT();
}
/**
* Intent data contains gatekeeper password handle or not
*/
public static boolean containsGatekeeperPasswordHandle(@Nullable Intent data) {
return data != null && data.hasExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE);
}
/**
* Returns the gatekeeper password handle from intent
*/
public static long getGatekeeperPasswordHandle(@NonNull Intent data) {
return data.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, 0L);
}
/**
* Requests {@link com.android.server.locksettings.LockSettingsService} to remove the
* gatekeeper password associated with a previous
* {@link ChooseLockSettingsHelper.Builder#setRequestGatekeeperPasswordHandle(boolean)}
*
* @param data The onActivityResult intent from ChooseLock* or ConfirmLock*
* @param alsoRemoveItFromIntent set it to true if gkPwHandle needs to be removed from intent
*/
public void removeGatekeeperPasswordHandle(@Nullable Intent data,
boolean alsoRemoveItFromIntent) {
if (data == null) {
return;
}
if (!containsGatekeeperPasswordHandle(data)) {
return;
}
removeGatekeeperPasswordHandle(getGatekeeperPasswordHandle(data));
if (alsoRemoveItFromIntent) {
data.removeExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE);
}
}
/**
* Requests {@link com.android.server.locksettings.LockSettingsService} to remove the
* gatekeeper password associated with a previous
* {@link ChooseLockSettingsHelper.Builder#setRequestGatekeeperPasswordHandle(boolean)}
*
* @param handle The Gatekeeper password handle from ChooseLock* or ConfirmLock*
*/
public void removeGatekeeperPasswordHandle(long handle) {
mLockPatternUtils.removeGatekeeperPasswordHandle(handle);
Log.d(TAG, "Removed handle");
}
}