Merge "Added FingerprintInteractiveToAuthProvider" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
103ab3935b
@@ -141,6 +141,7 @@ import com.android.settingslib.fuelgauge.BatteryStatus;
|
|||||||
import com.android.systemui.Dumpable;
|
import com.android.systemui.Dumpable;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.biometrics.AuthController;
|
import com.android.systemui.biometrics.AuthController;
|
||||||
|
import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
import com.android.systemui.dagger.SysUISingleton;
|
||||||
import com.android.systemui.dagger.qualifiers.Background;
|
import com.android.systemui.dagger.qualifiers.Background;
|
||||||
@@ -170,6 +171,7 @@ import java.util.Iterator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
@@ -345,13 +347,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
|
private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
|
||||||
mCallbacks = Lists.newArrayList();
|
mCallbacks = Lists.newArrayList();
|
||||||
private ContentObserver mDeviceProvisionedObserver;
|
private ContentObserver mDeviceProvisionedObserver;
|
||||||
private ContentObserver mSfpsRequireScreenOnToAuthPrefObserver;
|
|
||||||
private final ContentObserver mTimeFormatChangeObserver;
|
private final ContentObserver mTimeFormatChangeObserver;
|
||||||
|
|
||||||
private boolean mSwitchingUser;
|
private boolean mSwitchingUser;
|
||||||
|
|
||||||
private boolean mDeviceInteractive;
|
private boolean mDeviceInteractive;
|
||||||
private boolean mSfpsRequireScreenOnToAuthPrefEnabled;
|
|
||||||
private final SubscriptionManager mSubscriptionManager;
|
private final SubscriptionManager mSubscriptionManager;
|
||||||
private final TelephonyListenerManager mTelephonyListenerManager;
|
private final TelephonyListenerManager mTelephonyListenerManager;
|
||||||
private final TrustManager mTrustManager;
|
private final TrustManager mTrustManager;
|
||||||
@@ -384,6 +384,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
private boolean mLogoutEnabled;
|
private boolean mLogoutEnabled;
|
||||||
private boolean mIsFaceEnrolled;
|
private boolean mIsFaceEnrolled;
|
||||||
private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||||
|
private FingerprintInteractiveToAuthProvider mFingerprintInteractiveToAuthProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Short delay before restarting fingerprint authentication after a successful try. This should
|
* Short delay before restarting fingerprint authentication after a successful try. This should
|
||||||
@@ -2055,7 +2056,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
@Nullable FaceManager faceManager,
|
@Nullable FaceManager faceManager,
|
||||||
@Nullable FingerprintManager fingerprintManager,
|
@Nullable FingerprintManager fingerprintManager,
|
||||||
@Nullable BiometricManager biometricManager,
|
@Nullable BiometricManager biometricManager,
|
||||||
FaceWakeUpTriggersConfig faceWakeUpTriggersConfig) {
|
FaceWakeUpTriggersConfig faceWakeUpTriggersConfig,
|
||||||
|
Optional<FingerprintInteractiveToAuthProvider> interactiveToAuthProvider) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mSubscriptionManager = subscriptionManager;
|
mSubscriptionManager = subscriptionManager;
|
||||||
mUserTracker = userTracker;
|
mUserTracker = userTracker;
|
||||||
@@ -2318,30 +2320,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
Settings.System.getUriFor(Settings.System.TIME_12_24),
|
Settings.System.getUriFor(Settings.System.TIME_12_24),
|
||||||
false, mTimeFormatChangeObserver, UserHandle.USER_ALL);
|
false, mTimeFormatChangeObserver, UserHandle.USER_ALL);
|
||||||
|
|
||||||
updateSfpsRequireScreenOnToAuthPref();
|
mFingerprintInteractiveToAuthProvider = interactiveToAuthProvider.orElse(null);
|
||||||
mSfpsRequireScreenOnToAuthPrefObserver = new ContentObserver(mHandler) {
|
|
||||||
@Override
|
|
||||||
public void onChange(boolean selfChange) {
|
|
||||||
updateSfpsRequireScreenOnToAuthPref();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mContext.getContentResolver().registerContentObserver(
|
|
||||||
mSecureSettings.getUriFor(
|
|
||||||
Settings.Secure.SFPS_REQUIRE_SCREEN_ON_TO_AUTH_ENABLED),
|
|
||||||
false,
|
|
||||||
mSfpsRequireScreenOnToAuthPrefObserver,
|
|
||||||
getCurrentUser());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updateSfpsRequireScreenOnToAuthPref() {
|
|
||||||
final int defaultSfpsRequireScreenOnToAuthValue =
|
|
||||||
mContext.getResources().getBoolean(
|
|
||||||
com.android.internal.R.bool.config_requireScreenOnToAuthEnabled) ? 1 : 0;
|
|
||||||
mSfpsRequireScreenOnToAuthPrefEnabled = mSecureSettings.getIntForUser(
|
|
||||||
Settings.Secure.SFPS_REQUIRE_SCREEN_ON_TO_AUTH_ENABLED,
|
|
||||||
defaultSfpsRequireScreenOnToAuthValue,
|
|
||||||
getCurrentUser()) != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeSimState() {
|
private void initializeSimState() {
|
||||||
@@ -2736,8 +2715,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
|
|
||||||
boolean shouldListenSideFpsState = true;
|
boolean shouldListenSideFpsState = true;
|
||||||
if (isSideFps) {
|
if (isSideFps) {
|
||||||
|
final boolean interactiveToAuthEnabled =
|
||||||
|
mFingerprintInteractiveToAuthProvider != null &&
|
||||||
|
mFingerprintInteractiveToAuthProvider.isEnabled(getCurrentUser());
|
||||||
shouldListenSideFpsState =
|
shouldListenSideFpsState =
|
||||||
mSfpsRequireScreenOnToAuthPrefEnabled ? isDeviceInteractive() : true;
|
interactiveToAuthEnabled ? isDeviceInteractive() : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean shouldListen = shouldListenKeyguardState && shouldListenUserState
|
boolean shouldListen = shouldListenKeyguardState && shouldListenUserState
|
||||||
@@ -3852,11 +3834,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
mContext.getContentResolver().unregisterContentObserver(mTimeFormatChangeObserver);
|
mContext.getContentResolver().unregisterContentObserver(mTimeFormatChangeObserver);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSfpsRequireScreenOnToAuthPrefObserver != null) {
|
|
||||||
mContext.getContentResolver().unregisterContentObserver(
|
|
||||||
mSfpsRequireScreenOnToAuthPrefObserver);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ActivityManager.getService().unregisterUserSwitchObserver(mUserSwitchObserver);
|
ActivityManager.getService().unregisterUserSwitchObserver(mUserSwitchObserver);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -3933,8 +3910,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
} else if (isSfpsSupported()) {
|
} else if (isSfpsSupported()) {
|
||||||
pw.println(" sfpsEnrolled=" + isSfpsEnrolled());
|
pw.println(" sfpsEnrolled=" + isSfpsEnrolled());
|
||||||
pw.println(" shouldListenForSfps=" + shouldListenForFingerprint(false));
|
pw.println(" shouldListenForSfps=" + shouldListenForFingerprint(false));
|
||||||
pw.println(" mSfpsRequireScreenOnToAuthPrefEnabled="
|
if (isSfpsEnrolled()) {
|
||||||
+ mSfpsRequireScreenOnToAuthPrefEnabled);
|
final boolean interactiveToAuthEnabled =
|
||||||
|
mFingerprintInteractiveToAuthProvider != null &&
|
||||||
|
mFingerprintInteractiveToAuthProvider
|
||||||
|
.isEnabled(getCurrentUser());
|
||||||
|
pw.println(" interactiveToAuthEnabled="
|
||||||
|
+ interactiveToAuthEnabled);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
new DumpsysTableLogger(
|
new DumpsysTableLogger(
|
||||||
"KeyguardFingerprintListen",
|
"KeyguardFingerprintListen",
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 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.systemui.biometrics;
|
||||||
|
|
||||||
|
/** Provides the status of the interactive to auth feature. */
|
||||||
|
public interface FingerprintInteractiveToAuthProvider {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param userId the user Id.
|
||||||
|
* @return true if the InteractiveToAuthFeature is enabled, false if disabled.
|
||||||
|
*/
|
||||||
|
boolean isEnabled(int userId);
|
||||||
|
}
|
||||||
@@ -31,6 +31,7 @@ import com.android.systemui.BootCompleteCacheImpl;
|
|||||||
import com.android.systemui.appops.dagger.AppOpsModule;
|
import com.android.systemui.appops.dagger.AppOpsModule;
|
||||||
import com.android.systemui.assist.AssistModule;
|
import com.android.systemui.assist.AssistModule;
|
||||||
import com.android.systemui.biometrics.AlternateUdfpsTouchProvider;
|
import com.android.systemui.biometrics.AlternateUdfpsTouchProvider;
|
||||||
|
import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
|
||||||
import com.android.systemui.biometrics.UdfpsDisplayModeProvider;
|
import com.android.systemui.biometrics.UdfpsDisplayModeProvider;
|
||||||
import com.android.systemui.biometrics.dagger.BiometricsModule;
|
import com.android.systemui.biometrics.dagger.BiometricsModule;
|
||||||
import com.android.systemui.biometrics.dagger.UdfpsModule;
|
import com.android.systemui.biometrics.dagger.UdfpsModule;
|
||||||
@@ -221,6 +222,9 @@ public abstract class SystemUIModule {
|
|||||||
@BindsOptionalOf
|
@BindsOptionalOf
|
||||||
abstract AlternateUdfpsTouchProvider optionalUdfpsTouchProvider();
|
abstract AlternateUdfpsTouchProvider optionalUdfpsTouchProvider();
|
||||||
|
|
||||||
|
@BindsOptionalOf
|
||||||
|
abstract FingerprintInteractiveToAuthProvider optionalFingerprintInteractiveToAuthProvider();
|
||||||
|
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
@Binds
|
@Binds
|
||||||
abstract SystemClock bindSystemClock(SystemClockImpl systemClock);
|
abstract SystemClock bindSystemClock(SystemClockImpl systemClock);
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ import com.android.keyguard.KeyguardUpdateMonitor.BiometricAuthenticated;
|
|||||||
import com.android.keyguard.logging.KeyguardUpdateMonitorLogger;
|
import com.android.keyguard.logging.KeyguardUpdateMonitorLogger;
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
import com.android.systemui.biometrics.AuthController;
|
import com.android.systemui.biometrics.AuthController;
|
||||||
|
import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||||
import com.android.systemui.dump.DumpManager;
|
import com.android.systemui.dump.DumpManager;
|
||||||
import com.android.systemui.log.SessionTracker;
|
import com.android.systemui.log.SessionTracker;
|
||||||
@@ -142,6 +143,7 @@ import org.mockito.internal.util.reflection.FieldSetter;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
@@ -233,6 +235,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
@Mock
|
@Mock
|
||||||
private GlobalSettings mGlobalSettings;
|
private GlobalSettings mGlobalSettings;
|
||||||
private FaceWakeUpTriggersConfig mFaceWakeUpTriggersConfig;
|
private FaceWakeUpTriggersConfig mFaceWakeUpTriggersConfig;
|
||||||
|
@Mock
|
||||||
|
private FingerprintInteractiveToAuthProvider mInteractiveToAuthProvider;
|
||||||
|
|
||||||
|
|
||||||
private final int mCurrentUserId = 100;
|
private final int mCurrentUserId = 100;
|
||||||
@@ -1259,8 +1263,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
|
when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
|
||||||
|
|
||||||
// WHEN require screen on to auth is disabled, and keyguard is not awake
|
// WHEN require screen on to auth is disabled, and keyguard is not awake
|
||||||
when(mSecureSettings.getIntForUser(anyString(), anyInt(), anyInt())).thenReturn(0);
|
when(mInteractiveToAuthProvider.isEnabled(anyInt())).thenReturn(false);
|
||||||
mKeyguardUpdateMonitor.updateSfpsRequireScreenOnToAuthPref();
|
|
||||||
|
|
||||||
mContext.getOrCreateTestableResources().addOverride(
|
mContext.getOrCreateTestableResources().addOverride(
|
||||||
com.android.internal.R.bool.config_requireScreenOnToAuthEnabled, true);
|
com.android.internal.R.bool.config_requireScreenOnToAuthEnabled, true);
|
||||||
@@ -1280,8 +1283,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isTrue();
|
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isTrue();
|
||||||
|
|
||||||
// WHEN require screen on to auth is enabled, and keyguard is not awake
|
// WHEN require screen on to auth is enabled, and keyguard is not awake
|
||||||
when(mSecureSettings.getIntForUser(anyString(), anyInt(), anyInt())).thenReturn(1);
|
when(mInteractiveToAuthProvider.isEnabled(anyInt())).thenReturn(true);
|
||||||
mKeyguardUpdateMonitor.updateSfpsRequireScreenOnToAuthPref();
|
|
||||||
|
|
||||||
// THEN we shouldn't listen for sfps when screen off, because require screen on is enabled
|
// THEN we shouldn't listen for sfps when screen off, because require screen on is enabled
|
||||||
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isFalse();
|
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isFalse();
|
||||||
@@ -2407,7 +2409,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
mPowerManager, mTrustManager, mSubscriptionManager, mUserManager,
|
mPowerManager, mTrustManager, mSubscriptionManager, mUserManager,
|
||||||
mDreamManager, mDevicePolicyManager, mSensorPrivacyManager, mTelephonyManager,
|
mDreamManager, mDevicePolicyManager, mSensorPrivacyManager, mTelephonyManager,
|
||||||
mPackageManager, mFaceManager, mFingerprintManager, mBiometricManager,
|
mPackageManager, mFaceManager, mFingerprintManager, mBiometricManager,
|
||||||
mFaceWakeUpTriggersConfig);
|
mFaceWakeUpTriggersConfig, Optional.of(mInteractiveToAuthProvider));
|
||||||
setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
|
setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,15 +16,11 @@
|
|||||||
|
|
||||||
package com.android.server.biometrics.sensors.fingerprint.aidl;
|
package com.android.server.biometrics.sensors.fingerprint.aidl;
|
||||||
|
|
||||||
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START;
|
|
||||||
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR;
|
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.app.TaskStackListener;
|
import android.app.TaskStackListener;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.hardware.biometrics.BiometricAuthenticator;
|
import android.hardware.biometrics.BiometricAuthenticator;
|
||||||
import android.hardware.biometrics.BiometricConstants;
|
|
||||||
import android.hardware.biometrics.BiometricFingerprintConstants;
|
import android.hardware.biometrics.BiometricFingerprintConstants;
|
||||||
import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired;
|
import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired;
|
||||||
import android.hardware.biometrics.common.ICancellationSignal;
|
import android.hardware.biometrics.common.ICancellationSignal;
|
||||||
@@ -92,7 +88,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
|||||||
private long mSideFpsLastAcquireStartTime;
|
private long mSideFpsLastAcquireStartTime;
|
||||||
private Runnable mAuthSuccessRunnable;
|
private Runnable mAuthSuccessRunnable;
|
||||||
private final Clock mClock;
|
private final Clock mClock;
|
||||||
private boolean mDidFinishSfps;
|
|
||||||
|
|
||||||
FingerprintAuthenticationClient(
|
FingerprintAuthenticationClient(
|
||||||
@NonNull Context context,
|
@NonNull Context context,
|
||||||
@@ -198,9 +193,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleLifecycleAfterAuth(boolean authenticated) {
|
protected void handleLifecycleAfterAuth(boolean authenticated) {
|
||||||
if (authenticated && !mDidFinishSfps) {
|
if (authenticated) {
|
||||||
mCallback.onClientFinished(this, true /* success */);
|
mCallback.onClientFinished(this, true /* success */);
|
||||||
mDidFinishSfps = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,13 +204,11 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleAuthenticate(
|
@Override
|
||||||
|
public void onAuthenticated(
|
||||||
BiometricAuthenticator.Identifier identifier,
|
BiometricAuthenticator.Identifier identifier,
|
||||||
boolean authenticated,
|
boolean authenticated,
|
||||||
ArrayList<Byte> token) {
|
ArrayList<Byte> token) {
|
||||||
if (authenticated && mSensorProps.isAnySidefpsType()) {
|
|
||||||
Slog.i(TAG, "(sideFPS): No power press detected, sending auth");
|
|
||||||
}
|
|
||||||
super.onAuthenticated(identifier, authenticated, token);
|
super.onAuthenticated(identifier, authenticated, token);
|
||||||
if (authenticated) {
|
if (authenticated) {
|
||||||
mState = STATE_STOPPED;
|
mState = STATE_STOPPED;
|
||||||
@@ -226,73 +218,12 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAuthenticated(
|
|
||||||
BiometricAuthenticator.Identifier identifier,
|
|
||||||
boolean authenticated,
|
|
||||||
ArrayList<Byte> token) {
|
|
||||||
|
|
||||||
mHandler.post(
|
|
||||||
() -> {
|
|
||||||
long delay = 0;
|
|
||||||
if (authenticated && mSensorProps.isAnySidefpsType()) {
|
|
||||||
delay = isKeyguard() ? mWaitForAuthKeyguard : mWaitForAuthBp;
|
|
||||||
|
|
||||||
if (mSideFpsLastAcquireStartTime != -1) {
|
|
||||||
delay = Math.max(0,
|
|
||||||
delay - (mClock.millis() - mSideFpsLastAcquireStartTime));
|
|
||||||
}
|
|
||||||
|
|
||||||
Slog.i(TAG, "(sideFPS) Auth succeeded, sideFps "
|
|
||||||
+ "waiting for power until: " + delay + "ms");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mHandler.hasMessages(MESSAGE_FINGER_UP)) {
|
|
||||||
Slog.i(TAG, "Finger up detected, sending auth");
|
|
||||||
delay = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mAuthSuccessRunnable =
|
|
||||||
() -> handleAuthenticate(identifier, authenticated, token);
|
|
||||||
mHandler.postDelayed(
|
|
||||||
mAuthSuccessRunnable,
|
|
||||||
MESSAGE_AUTH_SUCCESS,
|
|
||||||
delay);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAcquired(@FingerprintAcquired int acquiredInfo, int vendorCode) {
|
public void onAcquired(@FingerprintAcquired int acquiredInfo, int vendorCode) {
|
||||||
// For UDFPS, notify SysUI with acquiredInfo, so that the illumination can be turned off
|
// For UDFPS, notify SysUI with acquiredInfo, so that the illumination can be turned off
|
||||||
// for most ACQUIRED messages. See BiometricFingerprintConstants#FingerprintAcquired
|
// for most ACQUIRED messages. See BiometricFingerprintConstants#FingerprintAcquired
|
||||||
mSensorOverlays.ifUdfps(controller -> controller.onAcquired(getSensorId(), acquiredInfo));
|
mSensorOverlays.ifUdfps(controller -> controller.onAcquired(getSensorId(), acquiredInfo));
|
||||||
super.onAcquired(acquiredInfo, vendorCode);
|
super.onAcquired(acquiredInfo, vendorCode);
|
||||||
if (mSensorProps.isAnySidefpsType()) {
|
|
||||||
if (acquiredInfo == FINGERPRINT_ACQUIRED_START) {
|
|
||||||
mSideFpsLastAcquireStartTime = mClock.millis();
|
|
||||||
}
|
|
||||||
final boolean shouldLookForVendor =
|
|
||||||
mSkipWaitForPowerAcquireMessage == FINGERPRINT_ACQUIRED_VENDOR;
|
|
||||||
final boolean acquireMessageMatch = acquiredInfo == mSkipWaitForPowerAcquireMessage;
|
|
||||||
final boolean vendorMessageMatch = vendorCode == mSkipWaitForPowerVendorAcquireMessage;
|
|
||||||
final boolean ignorePowerPress =
|
|
||||||
acquireMessageMatch && (!shouldLookForVendor || vendorMessageMatch);
|
|
||||||
|
|
||||||
if (ignorePowerPress) {
|
|
||||||
Slog.d(TAG, "(sideFPS) onFingerUp");
|
|
||||||
mHandler.post(() -> {
|
|
||||||
if (mHandler.hasMessages(MESSAGE_AUTH_SUCCESS)) {
|
|
||||||
Slog.d(TAG, "(sideFPS) skipping wait for power");
|
|
||||||
mHandler.removeMessages(MESSAGE_AUTH_SUCCESS);
|
|
||||||
mHandler.post(mAuthSuccessRunnable);
|
|
||||||
} else {
|
|
||||||
mHandler.postDelayed(() -> {
|
|
||||||
}, MESSAGE_FINGER_UP, mFingerUpIgnoresPower);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -488,22 +419,5 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPowerPressed() {
|
public void onPowerPressed() { }
|
||||||
if (mSensorProps.isAnySidefpsType()) {
|
|
||||||
Slog.i(TAG, "(sideFPS): onPowerPressed");
|
|
||||||
mHandler.post(() -> {
|
|
||||||
if (mDidFinishSfps) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Slog.i(TAG, "(sideFPS): finishing auth");
|
|
||||||
// Ignore auths after a power has been detected
|
|
||||||
mHandler.removeMessages(MESSAGE_AUTH_SUCCESS);
|
|
||||||
// Do not call onError() as that will send an additional callback to coex.
|
|
||||||
mDidFinishSfps = true;
|
|
||||||
onErrorInternal(BiometricConstants.BIOMETRIC_ERROR_POWER_PRESSED, 0, true);
|
|
||||||
stopHalOperation();
|
|
||||||
mSensorOverlays.hide(getSensorId());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ import android.hardware.biometrics.common.OperationContext;
|
|||||||
import android.hardware.biometrics.fingerprint.ISession;
|
import android.hardware.biometrics.fingerprint.ISession;
|
||||||
import android.hardware.biometrics.fingerprint.PointerContext;
|
import android.hardware.biometrics.fingerprint.PointerContext;
|
||||||
import android.hardware.fingerprint.Fingerprint;
|
import android.hardware.fingerprint.Fingerprint;
|
||||||
import android.hardware.fingerprint.FingerprintManager;
|
|
||||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||||
import android.hardware.fingerprint.ISidefpsController;
|
import android.hardware.fingerprint.ISidefpsController;
|
||||||
import android.hardware.fingerprint.IUdfpsOverlayController;
|
import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||||
@@ -55,7 +54,6 @@ import android.testing.TestableContext;
|
|||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
import androidx.test.platform.app.InstrumentationRegistry;
|
import androidx.test.platform.app.InstrumentationRegistry;
|
||||||
|
|
||||||
import com.android.internal.R;
|
|
||||||
import com.android.server.biometrics.log.BiometricContext;
|
import com.android.server.biometrics.log.BiometricContext;
|
||||||
import com.android.server.biometrics.log.BiometricLogger;
|
import com.android.server.biometrics.log.BiometricLogger;
|
||||||
import com.android.server.biometrics.log.CallbackWithProbe;
|
import com.android.server.biometrics.log.CallbackWithProbe;
|
||||||
@@ -369,274 +367,6 @@ public class FingerprintAuthenticationClientTest {
|
|||||||
verify(mCancellationSignal).cancel();
|
verify(mCancellationSignal).cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void fingerprintPowerIgnoresAuthInWindow() throws Exception {
|
|
||||||
when(mSensorProps.isAnySidefpsType()).thenReturn(true);
|
|
||||||
when(mHal.authenticate(anyLong())).thenReturn(mCancellationSignal);
|
|
||||||
|
|
||||||
final FingerprintAuthenticationClient client = createClient(1);
|
|
||||||
client.start(mCallback);
|
|
||||||
client.onPowerPressed();
|
|
||||||
client.onAuthenticated(new Fingerprint("friendly", 1 /* fingerId */, 2 /* deviceId */),
|
|
||||||
true /* authenticated */, new ArrayList<>());
|
|
||||||
mLooper.moveTimeForward(1000);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
|
|
||||||
verify(mCallback).onClientFinished(any(), eq(false));
|
|
||||||
verify(mCancellationSignal).cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void fingerprintAuthIgnoredWaitingForPower() throws Exception {
|
|
||||||
when(mSensorProps.isAnySidefpsType()).thenReturn(true);
|
|
||||||
when(mHal.authenticate(anyLong())).thenReturn(mCancellationSignal);
|
|
||||||
|
|
||||||
final FingerprintAuthenticationClient client = createClient(1);
|
|
||||||
client.start(mCallback);
|
|
||||||
client.onAuthenticated(new Fingerprint("friendly", 3 /* fingerId */, 4 /* deviceId */),
|
|
||||||
true /* authenticated */, new ArrayList<>());
|
|
||||||
client.onPowerPressed();
|
|
||||||
mLooper.moveTimeForward(1000);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
|
|
||||||
verify(mCallback).onClientFinished(any(), eq(false));
|
|
||||||
verify(mCancellationSignal).cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void fingerprintAuthFailsWhenAuthAfterPower() throws Exception {
|
|
||||||
when(mSensorProps.isAnySidefpsType()).thenReturn(true);
|
|
||||||
when(mHal.authenticate(anyLong())).thenReturn(mCancellationSignal);
|
|
||||||
|
|
||||||
final FingerprintAuthenticationClient client = createClient(1);
|
|
||||||
client.start(mCallback);
|
|
||||||
client.onPowerPressed();
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
mLooper.moveTimeForward(1000);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
|
|
||||||
true /* authenticated */, new ArrayList<>());
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
mLooper.moveTimeForward(1000);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
|
|
||||||
verify(mCallback, never()).onClientFinished(any(), eq(true));
|
|
||||||
verify(mCallback).onClientFinished(any(), eq(false));
|
|
||||||
when(mHal.authenticateWithContext(anyLong(), any())).thenReturn(mCancellationSignal);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void sideFingerprintDoesntSendAuthImmediately() throws Exception {
|
|
||||||
when(mSensorProps.isAnySidefpsType()).thenReturn(true);
|
|
||||||
|
|
||||||
final FingerprintAuthenticationClient client = createClient(1);
|
|
||||||
client.start(mCallback);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
|
|
||||||
true /* authenticated */, new ArrayList<>());
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
|
|
||||||
verify(mCallback, never()).onClientFinished(any(), anyBoolean());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void sideFingerprintSkipsWindowIfFingerUp() throws Exception {
|
|
||||||
when(mSensorProps.isAnySidefpsType()).thenReturn(true);
|
|
||||||
|
|
||||||
mContext.getOrCreateTestableResources().addOverride(
|
|
||||||
R.integer.config_sidefpsSkipWaitForPowerAcquireMessage, FINGER_UP);
|
|
||||||
|
|
||||||
final FingerprintAuthenticationClient client = createClient(1);
|
|
||||||
client.start(mCallback);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
|
|
||||||
true /* authenticated */, new ArrayList<>());
|
|
||||||
client.onAcquired(FINGER_UP, 0);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
|
|
||||||
verify(mCallback).onClientFinished(any(), eq(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void sideFingerprintSkipsWindowIfVendorMessageMatch() throws Exception {
|
|
||||||
when(mSensorProps.isAnySidefpsType()).thenReturn(true);
|
|
||||||
final int vendorAcquireMessage = 1234;
|
|
||||||
|
|
||||||
mContext.getOrCreateTestableResources().addOverride(
|
|
||||||
R.integer.config_sidefpsSkipWaitForPowerAcquireMessage,
|
|
||||||
FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR);
|
|
||||||
mContext.getOrCreateTestableResources().addOverride(
|
|
||||||
R.integer.config_sidefpsSkipWaitForPowerVendorAcquireMessage,
|
|
||||||
vendorAcquireMessage);
|
|
||||||
|
|
||||||
final FingerprintAuthenticationClient client = createClient(1);
|
|
||||||
client.start(mCallback);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
|
|
||||||
true /* authenticated */, new ArrayList<>());
|
|
||||||
client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR, vendorAcquireMessage);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
|
|
||||||
verify(mCallback).onClientFinished(any(), eq(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void sideFingerprintDoesNotSkipWindowOnVendorErrorMismatch() throws Exception {
|
|
||||||
when(mSensorProps.isAnySidefpsType()).thenReturn(true);
|
|
||||||
final int vendorAcquireMessage = 1234;
|
|
||||||
|
|
||||||
mContext.getOrCreateTestableResources().addOverride(
|
|
||||||
R.integer.config_sidefpsSkipWaitForPowerAcquireMessage,
|
|
||||||
FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR);
|
|
||||||
mContext.getOrCreateTestableResources().addOverride(
|
|
||||||
R.integer.config_sidefpsSkipWaitForPowerVendorAcquireMessage,
|
|
||||||
vendorAcquireMessage);
|
|
||||||
|
|
||||||
final FingerprintAuthenticationClient client = createClient(1);
|
|
||||||
client.start(mCallback);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
|
|
||||||
true /* authenticated */, new ArrayList<>());
|
|
||||||
client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR, 1);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
|
|
||||||
verify(mCallback, never()).onClientFinished(any(), anyBoolean());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void sideFingerprintSendsAuthIfFingerUp() throws Exception {
|
|
||||||
when(mSensorProps.isAnySidefpsType()).thenReturn(true);
|
|
||||||
|
|
||||||
mContext.getOrCreateTestableResources().addOverride(
|
|
||||||
R.integer.config_sidefpsSkipWaitForPowerAcquireMessage, FINGER_UP);
|
|
||||||
|
|
||||||
final FingerprintAuthenticationClient client = createClient(1);
|
|
||||||
client.start(mCallback);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
client.onAcquired(FINGER_UP, 0);
|
|
||||||
client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
|
|
||||||
true /* authenticated */, new ArrayList<>());
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
|
|
||||||
verify(mCallback).onClientFinished(any(), eq(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void sideFingerprintShortCircuitExpires() throws Exception {
|
|
||||||
when(mSensorProps.isAnySidefpsType()).thenReturn(true);
|
|
||||||
|
|
||||||
final int timeBeforeAuthSent = 500;
|
|
||||||
|
|
||||||
mContext.getOrCreateTestableResources().addOverride(
|
|
||||||
R.integer.config_sidefpsKeyguardPowerPressWindow, timeBeforeAuthSent);
|
|
||||||
mContext.getOrCreateTestableResources().addOverride(
|
|
||||||
R.integer.config_sidefpsSkipWaitForPowerAcquireMessage, FINGER_UP);
|
|
||||||
|
|
||||||
final FingerprintAuthenticationClient client = createClient(1);
|
|
||||||
client.start(mCallback);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
client.onAcquired(FINGER_UP, 0);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
|
|
||||||
mLooper.moveTimeForward(500);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
|
|
||||||
true /* authenticated */, new ArrayList<>());
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
verify(mCallback, never()).onClientFinished(any(), anyBoolean());
|
|
||||||
|
|
||||||
mLooper.moveTimeForward(500);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
verify(mCallback).onClientFinished(any(), eq(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void sideFingerprintPowerWindowStartsOnAcquireStart() throws Exception {
|
|
||||||
final int powerWindow = 500;
|
|
||||||
final long authStart = 300;
|
|
||||||
|
|
||||||
when(mSensorProps.isAnySidefpsType()).thenReturn(true);
|
|
||||||
mContext.getOrCreateTestableResources().addOverride(
|
|
||||||
R.integer.config_sidefpsBpPowerPressWindow, powerWindow);
|
|
||||||
|
|
||||||
final FingerprintAuthenticationClient client = createClient(1);
|
|
||||||
client.start(mCallback);
|
|
||||||
|
|
||||||
// Acquire start occurs at time = 0ms
|
|
||||||
when(mClock.millis()).thenReturn(0L);
|
|
||||||
client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_START, 0 /* vendorCode */);
|
|
||||||
|
|
||||||
// Auth occurs at time = 300
|
|
||||||
when(mClock.millis()).thenReturn(authStart);
|
|
||||||
// At this point the delay should be 500 - (300 - 0) == 200 milliseconds.
|
|
||||||
client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
|
|
||||||
true /* authenticated */, new ArrayList<>());
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
verify(mCallback, never()).onClientFinished(any(), anyBoolean());
|
|
||||||
|
|
||||||
// After waiting 200 milliseconds, auth should succeed.
|
|
||||||
mLooper.moveTimeForward(powerWindow - authStart);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
verify(mCallback).onClientFinished(any(), eq(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void sideFingerprintPowerWindowStartsOnLastAcquireStart() throws Exception {
|
|
||||||
final int powerWindow = 500;
|
|
||||||
|
|
||||||
when(mSensorProps.isAnySidefpsType()).thenReturn(true);
|
|
||||||
mContext.getOrCreateTestableResources().addOverride(
|
|
||||||
R.integer.config_sidefpsBpPowerPressWindow, powerWindow);
|
|
||||||
|
|
||||||
final FingerprintAuthenticationClient client = createClient(1);
|
|
||||||
client.start(mCallback);
|
|
||||||
// Acquire start occurs at time = 0ms
|
|
||||||
when(mClock.millis()).thenReturn(0L);
|
|
||||||
client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_START, 0 /* vendorCode */);
|
|
||||||
|
|
||||||
// Auth reject occurs at time = 300ms
|
|
||||||
when(mClock.millis()).thenReturn(300L);
|
|
||||||
client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
|
|
||||||
false /* authenticated */, new ArrayList<>());
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
|
|
||||||
mLooper.moveTimeForward(300);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
verify(mCallback, never()).onClientFinished(any(), anyBoolean());
|
|
||||||
|
|
||||||
when(mClock.millis()).thenReturn(1300L);
|
|
||||||
client.onAcquired(FingerprintManager.FINGERPRINT_ACQUIRED_START, 0 /* vendorCode */);
|
|
||||||
|
|
||||||
// If code is correct, the new acquired start timestamp should be used
|
|
||||||
// and the code should only have to wait 500 - (1500-1300)ms.
|
|
||||||
when(mClock.millis()).thenReturn(1500L);
|
|
||||||
client.onAuthenticated(new Fingerprint("friendly", 4 /* fingerId */, 5 /* deviceId */),
|
|
||||||
true /* authenticated */, new ArrayList<>());
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
|
|
||||||
mLooper.moveTimeForward(299);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
verify(mCallback, never()).onClientFinished(any(), anyBoolean());
|
|
||||||
|
|
||||||
mLooper.moveTimeForward(1);
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
verify(mCallback).onClientFinished(any(), eq(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void sideFpsPowerPressCancelsIsntantly() throws Exception {
|
|
||||||
when(mSensorProps.isAnySidefpsType()).thenReturn(true);
|
|
||||||
|
|
||||||
final FingerprintAuthenticationClient client = createClient(1);
|
|
||||||
client.start(mCallback);
|
|
||||||
|
|
||||||
client.onPowerPressed();
|
|
||||||
mLooper.dispatchAll();
|
|
||||||
|
|
||||||
verify(mCallback, never()).onClientFinished(any(), eq(true));
|
|
||||||
verify(mCallback).onClientFinished(any(), eq(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
private FingerprintAuthenticationClient createClient() throws RemoteException {
|
private FingerprintAuthenticationClient createClient() throws RemoteException {
|
||||||
return createClient(100 /* version */, true /* allowBackgroundAuthentication */);
|
return createClient(100 /* version */, true /* allowBackgroundAuthentication */);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user