Move fingerprint and face haptic form server to sysui(1/3)
BUG: 237621645
Test: Check the vibrator work normally when using biometric unlock
Change-Id: I16a847358fc0d4a5d486275a76a97a5195b2dddb
Merged-In: I16a847358fc0d4a5d486275a76a97a5195b2dddb
(cherry picked from commit 794db1b7f7)
This commit is contained in:
@@ -31,5 +31,4 @@
|
||||
lockscreen, setting this to true should come with customized drawables. -->
|
||||
<bool name="use_lock_pattern_drawable">false</bool>
|
||||
<bool name="resolver_landscape_phone">true</bool>
|
||||
<bool name="system_server_plays_face_haptics">true</bool>
|
||||
</resources>
|
||||
|
||||
@@ -4862,6 +4862,4 @@
|
||||
<java-symbol type="id" name="language_picker_header" />
|
||||
|
||||
<java-symbol type="dimen" name="status_bar_height_default" />
|
||||
|
||||
<java-symbol type="bool" name="system_server_plays_face_haptics" />
|
||||
</resources>
|
||||
|
||||
@@ -78,6 +78,7 @@ import com.android.systemui.doze.DozeReceiver;
|
||||
import com.android.systemui.keyguard.WakefulnessLifecycle;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
import com.android.systemui.statusbar.VibratorHelper;
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor;
|
||||
import com.android.systemui.util.concurrency.Execution;
|
||||
|
||||
@@ -160,6 +161,19 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
private final @Background DelayableExecutor mBackgroundExecutor;
|
||||
private final DisplayInfo mCachedDisplayInfo = new DisplayInfo();
|
||||
|
||||
|
||||
private final VibratorHelper mVibratorHelper;
|
||||
|
||||
private void vibrateSuccess(int modality) {
|
||||
mVibratorHelper.vibrateAuthSuccess(
|
||||
getClass().getSimpleName() + ", modality = " + modality + "BP::success");
|
||||
}
|
||||
|
||||
private void vibrateError(int modality) {
|
||||
mVibratorHelper.vibrateAuthError(
|
||||
getClass().getSimpleName() + ", modality = " + modality + "BP::error");
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
final TaskStackListener mTaskStackListener = new TaskStackListener() {
|
||||
@Override
|
||||
@@ -671,7 +685,8 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
@NonNull StatusBarStateController statusBarStateController,
|
||||
@NonNull InteractionJankMonitor jankMonitor,
|
||||
@Main Handler handler,
|
||||
@Background DelayableExecutor bgExecutor) {
|
||||
@Background DelayableExecutor bgExecutor,
|
||||
@NonNull VibratorHelper vibrator) {
|
||||
mContext = context;
|
||||
mExecution = execution;
|
||||
mUserManager = userManager;
|
||||
@@ -689,6 +704,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
mInteractionJankMonitor = jankMonitor;
|
||||
mUdfpsEnrolledForUser = new SparseBooleanArray();
|
||||
mSfpsEnrolledForUser = new SparseBooleanArray();
|
||||
mVibratorHelper = vibrator;
|
||||
|
||||
mOrientationListener = new BiometricDisplayListener(
|
||||
context,
|
||||
@@ -878,6 +894,8 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
public void onBiometricAuthenticated(@Modality int modality) {
|
||||
if (DEBUG) Log.d(TAG, "onBiometricAuthenticated: ");
|
||||
|
||||
vibrateSuccess(modality);
|
||||
|
||||
if (mCurrentDialog != null) {
|
||||
mCurrentDialog.onAuthenticationSucceeded(modality);
|
||||
} else {
|
||||
@@ -930,6 +948,8 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
Log.d(TAG, String.format("onBiometricError(%d, %d, %d)", modality, error, vendorCode));
|
||||
}
|
||||
|
||||
vibrateError(modality);
|
||||
|
||||
final boolean isLockout = (error == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT)
|
||||
|| (error == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.media.AudioAttributes;
|
||||
import android.os.Process;
|
||||
import android.os.VibrationAttributes;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
@@ -33,6 +34,7 @@ import java.util.concurrent.Executor;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@SysUISingleton
|
||||
public class VibratorHelper {
|
||||
@@ -40,9 +42,18 @@ public class VibratorHelper {
|
||||
private final Vibrator mVibrator;
|
||||
public static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES =
|
||||
VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH);
|
||||
|
||||
private static final VibrationEffect BIOMETRIC_SUCCESS_VIBRATION_EFFECT =
|
||||
VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
|
||||
private static final VibrationEffect BIOMETRIC_ERROR_VIBRATION_EFFECT =
|
||||
VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
|
||||
private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES =
|
||||
VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK);
|
||||
|
||||
private final Executor mExecutor;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Inject
|
||||
public VibratorHelper(@Nullable Vibrator vibrator, @Background Executor executor) {
|
||||
@@ -109,4 +120,23 @@ public class VibratorHelper {
|
||||
}
|
||||
mExecutor.execute(mVibrator::cancel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform vibration when biometric authentication success
|
||||
*/
|
||||
public void vibrateAuthSuccess(String reason) {
|
||||
vibrate(Process.myUid(),
|
||||
"com.android.systemui",
|
||||
BIOMETRIC_SUCCESS_VIBRATION_EFFECT, reason,
|
||||
HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform vibration when biometric authentication error
|
||||
*/
|
||||
public void vibrateAuthError(String reason) {
|
||||
vibrate(Process.myUid(), "com.android.systemui",
|
||||
BIOMETRIC_ERROR_VIBRATION_EFFECT, reason,
|
||||
HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,11 +27,8 @@ import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.metrics.LogMaker;
|
||||
import android.os.Handler;
|
||||
import android.os.PowerManager;
|
||||
import android.os.Process;
|
||||
import android.os.SystemClock;
|
||||
import android.os.Trace;
|
||||
import android.os.VibrationAttributes;
|
||||
import android.os.VibrationEffect;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -87,12 +84,6 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
private static final String BIOMETRIC_WAKE_LOCK_NAME = "wake-and-unlock:wakelock";
|
||||
private static final UiEventLogger UI_EVENT_LOGGER = new UiEventLoggerImpl();
|
||||
private static final int UDFPS_ATTEMPTS_BEFORE_SHOW_BOUNCER = 3;
|
||||
private static final VibrationEffect SUCCESS_VIBRATION_EFFECT =
|
||||
VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
|
||||
private static final VibrationEffect ERROR_VIBRATION_EFFECT =
|
||||
VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
|
||||
private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES =
|
||||
VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK);
|
||||
|
||||
@IntDef(prefix = { "MODE_" }, value = {
|
||||
MODE_NONE,
|
||||
@@ -167,7 +158,6 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
private final NotificationShadeWindowController mNotificationShadeWindowController;
|
||||
private final SessionTracker mSessionTracker;
|
||||
private final int mConsecutiveFpFailureThreshold;
|
||||
private final boolean mShouldVibrate;
|
||||
private int mMode;
|
||||
private BiometricSourceType mBiometricType;
|
||||
private KeyguardViewController mKeyguardViewController;
|
||||
@@ -307,8 +297,6 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
mHandler = handler;
|
||||
mConsecutiveFpFailureThreshold = resources.getInteger(
|
||||
R.integer.fp_consecutive_failure_time_ms);
|
||||
mShouldVibrate = !(resources.getBoolean(
|
||||
com.android.internal.R.bool.system_server_plays_face_haptics));
|
||||
mKeyguardBypassController = keyguardBypassController;
|
||||
mKeyguardBypassController.setUnlockController(this);
|
||||
mMetricsLogger = metricsLogger;
|
||||
@@ -423,10 +411,10 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
public void startWakeAndUnlock(BiometricSourceType biometricSourceType,
|
||||
boolean isStrongBiometric) {
|
||||
int mode = calculateMode(biometricSourceType, isStrongBiometric);
|
||||
if (BiometricSourceType.FACE == biometricSourceType && (mode == MODE_WAKE_AND_UNLOCK
|
||||
if (mode == MODE_WAKE_AND_UNLOCK
|
||||
|| mode == MODE_WAKE_AND_UNLOCK_PULSING || mode == MODE_UNLOCK_COLLAPSING
|
||||
|| mode == MODE_WAKE_AND_UNLOCK_FROM_DREAM || mode == MODE_DISMISS_BOUNCER)) {
|
||||
vibrateSuccess();
|
||||
|| mode == MODE_WAKE_AND_UNLOCK_FROM_DREAM || mode == MODE_DISMISS_BOUNCER) {
|
||||
vibrateSuccess(biometricSourceType);
|
||||
}
|
||||
startWakeAndUnlock(mode);
|
||||
}
|
||||
@@ -659,10 +647,11 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
}
|
||||
|
||||
// Suppress all face auth errors if fingerprint can be used to authenticate
|
||||
if (biometricSourceType == BiometricSourceType.FACE
|
||||
if ((biometricSourceType == BiometricSourceType.FACE
|
||||
&& !mUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
|
||||
KeyguardUpdateMonitor.getCurrentUser())) {
|
||||
vibrateError();
|
||||
KeyguardUpdateMonitor.getCurrentUser()))
|
||||
|| (biometricSourceType == BiometricSourceType.FINGERPRINT)) {
|
||||
vibrateError(biometricSourceType);
|
||||
}
|
||||
|
||||
cleanup();
|
||||
@@ -688,24 +677,15 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
cleanup();
|
||||
}
|
||||
|
||||
private void vibrateSuccess() {
|
||||
if (mShouldVibrate) {
|
||||
mVibratorHelper.vibrate(Process.myUid(),
|
||||
"com.android.systemui",
|
||||
SUCCESS_VIBRATION_EFFECT,
|
||||
getClass().getSimpleName() + "::success",
|
||||
HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES);
|
||||
}
|
||||
//these haptics are for device-entry only
|
||||
private void vibrateSuccess(BiometricSourceType type) {
|
||||
mVibratorHelper.vibrateAuthSuccess(
|
||||
getClass().getSimpleName() + ", type =" + type + "device-entry::success");
|
||||
}
|
||||
|
||||
private void vibrateError() {
|
||||
if (mShouldVibrate) {
|
||||
mVibratorHelper.vibrate(Process.myUid(),
|
||||
"com.android.systemui",
|
||||
ERROR_VIBRATION_EFFECT,
|
||||
getClass().getSimpleName() + "::error",
|
||||
HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES);
|
||||
}
|
||||
private void vibrateError(BiometricSourceType type) {
|
||||
mVibratorHelper.vibrateAuthError(
|
||||
getClass().getSimpleName() + ", type =" + type + "device-entry::error");
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
|
||||
@@ -87,6 +87,7 @@ import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.keyguard.WakefulnessLifecycle;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
import com.android.systemui.statusbar.VibratorHelper;
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor;
|
||||
import com.android.systemui.util.concurrency.Execution;
|
||||
import com.android.systemui.util.concurrency.FakeExecution;
|
||||
@@ -173,6 +174,9 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
private DelayableExecutor mBackgroundExecutor;
|
||||
private TestableAuthController mAuthController;
|
||||
|
||||
@Mock
|
||||
private VibratorHelper mVibratorHelper;
|
||||
|
||||
@Before
|
||||
public void setup() throws RemoteException {
|
||||
mContextSpy = spy(mContext);
|
||||
@@ -221,7 +225,8 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
|
||||
mAuthController = new TestableAuthController(mContextSpy, mExecution, mCommandQueue,
|
||||
mActivityTaskManager, mWindowManager, mFingerprintManager, mFaceManager,
|
||||
() -> mUdfpsController, () -> mSidefpsController, mStatusBarStateController);
|
||||
() -> mUdfpsController, () -> mSidefpsController, mStatusBarStateController,
|
||||
mVibratorHelper);
|
||||
|
||||
mAuthController.start();
|
||||
verify(mFingerprintManager).addAuthenticatorsRegisteredCallback(
|
||||
@@ -246,11 +251,13 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
// This test is sensitive to prior FingerprintManager interactions.
|
||||
reset(mFingerprintManager);
|
||||
|
||||
when(mVibratorHelper.hasVibrator()).thenReturn(true);
|
||||
|
||||
// This test requires an uninitialized AuthController.
|
||||
AuthController authController = new TestableAuthController(mContextSpy, mExecution,
|
||||
mCommandQueue, mActivityTaskManager, mWindowManager, mFingerprintManager,
|
||||
mFaceManager, () -> mUdfpsController, () -> mSidefpsController,
|
||||
mStatusBarStateController);
|
||||
mStatusBarStateController, mVibratorHelper);
|
||||
authController.start();
|
||||
|
||||
verify(mFingerprintManager).addAuthenticatorsRegisteredCallback(
|
||||
@@ -270,11 +277,13 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
// This test is sensitive to prior FingerprintManager interactions.
|
||||
reset(mFingerprintManager);
|
||||
|
||||
when(mVibratorHelper.hasVibrator()).thenReturn(true);
|
||||
|
||||
// This test requires an uninitialized AuthController.
|
||||
AuthController authController = new TestableAuthController(mContextSpy, mExecution,
|
||||
mCommandQueue, mActivityTaskManager, mWindowManager, mFingerprintManager,
|
||||
mFaceManager, () -> mUdfpsController, () -> mSidefpsController,
|
||||
mStatusBarStateController);
|
||||
mStatusBarStateController, mVibratorHelper);
|
||||
authController.start();
|
||||
|
||||
verify(mFingerprintManager).addAuthenticatorsRegisteredCallback(
|
||||
@@ -928,12 +937,13 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
FaceManager faceManager,
|
||||
Provider<UdfpsController> udfpsControllerFactory,
|
||||
Provider<SidefpsController> sidefpsControllerFactory,
|
||||
StatusBarStateController statusBarStateController) {
|
||||
StatusBarStateController statusBarStateController,
|
||||
VibratorHelper vibratorHelper) {
|
||||
super(context, execution, commandQueue, activityTaskManager, windowManager,
|
||||
fingerprintManager, faceManager, udfpsControllerFactory,
|
||||
sidefpsControllerFactory, mDisplayManager, mWakefulnessLifecycle,
|
||||
mUserManager, mLockPatternUtils, statusBarStateController,
|
||||
mInteractionJankMonitor, mHandler, mBackgroundExecutor);
|
||||
mInteractionJankMonitor, mHandler, mBackgroundExecutor, vibratorHelper);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -100,9 +100,7 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
|
||||
isStrongBiometric, null /* taskStackListener */, lockoutCache,
|
||||
allowBackgroundAuthentication,
|
||||
context.getResources().getBoolean(
|
||||
com.android.internal.R.bool.system_server_plays_face_haptics)
|
||||
/* shouldVibrate */,
|
||||
false /* shouldVibrate */,
|
||||
isKeyguardBypassEnabled);
|
||||
setRequestId(requestId);
|
||||
mUsageStats = usageStats;
|
||||
|
||||
@@ -74,7 +74,7 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
|
||||
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
|
||||
owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
|
||||
isStrongBiometric, null /* taskStackListener */,
|
||||
lockoutTracker, allowBackgroundAuthentication, true /* shouldVibrate */,
|
||||
lockoutTracker, allowBackgroundAuthentication, false /* shouldVibrate */,
|
||||
isKeyguardBypassEnabled);
|
||||
setRequestId(requestId);
|
||||
mUsageStats = usageStats;
|
||||
|
||||
@@ -135,7 +135,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
taskStackListener,
|
||||
lockoutCache,
|
||||
allowBackgroundAuthentication,
|
||||
true /* shouldVibrate */,
|
||||
false /* shouldVibrate */,
|
||||
false /* isKeyguardBypassEnabled */);
|
||||
setRequestId(requestId);
|
||||
mLockoutCache = lockoutCache;
|
||||
|
||||
@@ -81,7 +81,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
|
||||
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
|
||||
owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
|
||||
isStrongBiometric, taskStackListener, lockoutTracker, allowBackgroundAuthentication,
|
||||
true /* shouldVibrate */, false /* isKeyguardBypassEnabled */);
|
||||
false /* shouldVibrate */, false /* isKeyguardBypassEnabled */);
|
||||
setRequestId(requestId);
|
||||
mLockoutFrameworkImpl = lockoutTracker;
|
||||
mSensorOverlays = new SensorOverlays(udfpsOverlayController, sidefpsController);
|
||||
|
||||
Reference in New Issue
Block a user