From 286813a76870c3a763fb22c46cebfe28fcb7bf75 Mon Sep 17 00:00:00 2001 From: Beverly Date: Thu, 15 Jul 2021 12:16:50 -0400 Subject: [PATCH] Add haptic feedback on the kg lock icon Test: manual, adb shell dumpsys vibrator_manager Bug: 193089985 Change-Id: I8c3e5d1931a3399d4ecf0aac501cd74e0b7d7bec --- .../keyguard/LockIconViewController.java | 32 ++++++++++++++++++- .../systemui/biometrics/UdfpsController.java | 8 ++++- .../biometrics/UdfpsControllerTest.java | 10 ++++-- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java index a7bd4c8e3d273..cc0381fa3b6fd 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java @@ -28,6 +28,9 @@ import android.graphics.drawable.AnimatedVectorDrawable; import android.graphics.drawable.Drawable; import android.hardware.biometrics.BiometricSourceType; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; +import android.media.AudioAttributes; +import android.os.Process; +import android.os.Vibrator; import android.util.DisplayMetrics; import android.view.GestureDetector; import android.view.GestureDetector.SimpleOnGestureListener; @@ -43,6 +46,7 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import com.android.systemui.Dumpable; import com.android.systemui.R; import com.android.systemui.biometrics.AuthController; +import com.android.systemui.biometrics.UdfpsController; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; import com.android.systemui.plugins.FalsingManager; @@ -67,6 +71,13 @@ import javax.inject.Inject; */ @StatusBarComponent.StatusBarScope public class LockIconViewController extends ViewController implements Dumpable { + + private static final AudioAttributes VIBRATION_SONIFICATION_ATTRIBUTES = + new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) + .build(); + @NonNull private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; @NonNull private final KeyguardViewController mKeyguardViewController; @NonNull private final StatusBarStateController mStatusBarStateController; @@ -83,6 +94,7 @@ public class LockIconViewController extends ViewController impleme @NonNull private final Drawable mLockIcon; @NonNull private final CharSequence mUnlockedLabel; @NonNull private final CharSequence mLockedLabel; + @Nullable private final Vibrator mVibrator; private boolean mIsDozing; private boolean mIsBouncerShowing; @@ -119,7 +131,8 @@ public class LockIconViewController extends ViewController impleme @NonNull DumpManager dumpManager, @NonNull AccessibilityManager accessibilityManager, @NonNull ConfigurationController configurationController, - @NonNull @Main DelayableExecutor executor + @NonNull @Main DelayableExecutor executor, + @Nullable Vibrator vibrator ) { super(view); mStatusBarStateController = statusBarStateController; @@ -131,6 +144,7 @@ public class LockIconViewController extends ViewController impleme mAccessibilityManager = accessibilityManager; mConfigurationController = configurationController; mExecutor = executor; + mVibrator = vibrator; final Context context = view.getContext(); mLockIcon = mView.getContext().getResources().getDrawable( @@ -459,6 +473,14 @@ public class LockIconViewController extends ViewController impleme // intercept all following touches until we see MotionEvent.ACTION_CANCEL UP or // MotionEvent.ACTION_UP (see #onTouchEvent) mDownDetected = true; + if (mVibrator != null) { + mVibrator.vibrate( + Process.myUid(), + getContext().getOpPackageName(), + UdfpsController.EFFECT_CLICK, + "lockIcon-onDown", + VIBRATION_SONIFICATION_ATTRIBUTES); + } return true; } @@ -467,6 +489,14 @@ public class LockIconViewController extends ViewController impleme return; } + if (mVibrator != null) { + mVibrator.vibrate( + Process.myUid(), + getContext().getOpPackageName(), + UdfpsController.EFFECT_CLICK, + "lockIcon-onLongPress", + VIBRATION_SONIFICATION_ATTRIBUTES); + } onAffordanceClick(); } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index c292dc4b988f8..6ddf248750004 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -40,6 +40,7 @@ import android.media.AudioAttributes; import android.os.Handler; import android.os.Looper; import android.os.PowerManager; +import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.Trace; @@ -569,7 +570,12 @@ public class UdfpsController implements DozeReceiver { @VisibleForTesting public void playStartHaptic() { if (mVibrator != null) { - mVibrator.vibrate(EFFECT_CLICK, VIBRATION_SONIFICATION_ATTRIBUTES); + mVibrator.vibrate( + Process.myUid(), + mContext.getOpPackageName(), + EFFECT_CLICK, + "udfps-onStart", + VIBRATION_SONIFICATION_ATTRIBUTES); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index 5156d7c2e87ab..397341b197ee2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -23,6 +23,8 @@ import static junit.framework.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyFloat; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -444,7 +446,11 @@ public class UdfpsControllerTest extends SysuiTestCase { moveEvent.recycle(); // THEN click haptic is played - verify(mVibrator).vibrate(mUdfpsController.EFFECT_CLICK, - UdfpsController.VIBRATION_SONIFICATION_ATTRIBUTES); + verify(mVibrator).vibrate( + anyInt(), + anyString(), + eq(mUdfpsController.EFFECT_CLICK), + eq("udfps-onStart"), + eq(UdfpsController.VIBRATION_SONIFICATION_ATTRIBUTES)); } }