Merge "Show UDFPS icon on AOD even if fp auth isn't running" into sc-dev am: e835dab9b8
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15838990 Change-Id: I6d2bd97b7d7093e48772d438b8a4a0a5cc97e618
This commit is contained in:
@@ -70,6 +70,19 @@
|
|||||||
android:padding="@dimen/lock_icon_padding"
|
android:padding="@dimen/lock_icon_padding"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:scaleType="centerCrop"/>
|
android:scaleType="centerCrop"/>
|
||||||
|
|
||||||
|
<!-- Fingerprint -->
|
||||||
|
<!-- AOD dashed fingerprint icon with moving dashes -->
|
||||||
|
<com.airbnb.lottie.LottieAnimationView
|
||||||
|
android:id="@+id/lock_udfps_aod_fp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="@dimen/lock_icon_padding"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
systemui:lottie_autoPlay="false"
|
||||||
|
systemui:lottie_loop="true"
|
||||||
|
systemui:lottie_rawRes="@raw/udfps_aod_fp"/>
|
||||||
</com.android.keyguard.LockIconView>
|
</com.android.keyguard.LockIconView>
|
||||||
|
|
||||||
<com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer
|
<com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class LockIconView extends FrameLayout implements Dumpable {
|
|||||||
private int mRadius;
|
private int mRadius;
|
||||||
|
|
||||||
private ImageView mLockIcon;
|
private ImageView mLockIcon;
|
||||||
private ImageView mUnlockBgView;
|
private ImageView mBgView;
|
||||||
|
|
||||||
private int mLockIconColor;
|
private int mLockIconColor;
|
||||||
|
|
||||||
@@ -57,19 +57,19 @@ public class LockIconView extends FrameLayout implements Dumpable {
|
|||||||
public void onFinishInflate() {
|
public void onFinishInflate() {
|
||||||
super.onFinishInflate();
|
super.onFinishInflate();
|
||||||
mLockIcon = findViewById(R.id.lock_icon);
|
mLockIcon = findViewById(R.id.lock_icon);
|
||||||
mUnlockBgView = findViewById(R.id.lock_icon_bg);
|
mBgView = findViewById(R.id.lock_icon_bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateColorAndBackgroundVisibility(boolean useBackground) {
|
void updateColorAndBackgroundVisibility(boolean useBackground) {
|
||||||
if (useBackground) {
|
if (useBackground && mLockIcon.getDrawable() != null) {
|
||||||
mLockIconColor = Utils.getColorAttrDefaultColor(getContext(),
|
mLockIconColor = Utils.getColorAttrDefaultColor(getContext(),
|
||||||
android.R.attr.textColorPrimary);
|
android.R.attr.textColorPrimary);
|
||||||
mUnlockBgView.setBackground(getContext().getDrawable(R.drawable.fingerprint_bg));
|
mBgView.setBackground(getContext().getDrawable(R.drawable.fingerprint_bg));
|
||||||
mUnlockBgView.setVisibility(View.VISIBLE);
|
mBgView.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
mLockIconColor = Utils.getColorAttrDefaultColor(getContext(),
|
mLockIconColor = Utils.getColorAttrDefaultColor(getContext(),
|
||||||
R.attr.wallpaperTextColorAccent);
|
R.attr.wallpaperTextColorAccent);
|
||||||
mUnlockBgView.setVisibility(View.GONE);
|
mBgView.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
mLockIcon.setImageTintList(ColorStateList.valueOf(mLockIconColor));
|
mLockIcon.setImageTintList(ColorStateList.valueOf(mLockIconColor));
|
||||||
@@ -77,9 +77,14 @@ public class LockIconView extends FrameLayout implements Dumpable {
|
|||||||
|
|
||||||
void setImageDrawable(Drawable drawable) {
|
void setImageDrawable(Drawable drawable) {
|
||||||
mLockIcon.setImageDrawable(drawable);
|
mLockIcon.setImageDrawable(drawable);
|
||||||
|
if (drawable == null) {
|
||||||
|
mBgView.setVisibility(View.INVISIBLE);
|
||||||
|
} else {
|
||||||
|
mBgView.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCenterLocation(@NonNull PointF center, int radius) {
|
public void setCenterLocation(@NonNull PointF center, int radius) {
|
||||||
mLockIconCenter = center;
|
mLockIconCenter = center;
|
||||||
mRadius = radius;
|
mRadius = radius;
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ package com.android.keyguard;
|
|||||||
import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
|
import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
|
||||||
|
|
||||||
import static com.android.systemui.classifier.Classifier.LOCK_ICON;
|
import static com.android.systemui.classifier.Classifier.LOCK_ICON;
|
||||||
|
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
|
||||||
|
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInProgressOffset;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
@@ -32,6 +34,7 @@ import android.media.AudioAttributes;
|
|||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.Vibrator;
|
import android.os.Vibrator;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
|
import android.util.MathUtils;
|
||||||
import android.view.GestureDetector;
|
import android.view.GestureDetector;
|
||||||
import android.view.GestureDetector.SimpleOnGestureListener;
|
import android.view.GestureDetector.SimpleOnGestureListener;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
@@ -58,6 +61,8 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
|
|||||||
import com.android.systemui.util.ViewController;
|
import com.android.systemui.util.ViewController;
|
||||||
import com.android.systemui.util.concurrency.DelayableExecutor;
|
import com.android.systemui.util.concurrency.DelayableExecutor;
|
||||||
|
|
||||||
|
import com.airbnb.lottie.LottieAnimationView;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -92,6 +97,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
|||||||
@NonNull private final DelayableExecutor mExecutor;
|
@NonNull private final DelayableExecutor mExecutor;
|
||||||
private boolean mUdfpsEnrolled;
|
private boolean mUdfpsEnrolled;
|
||||||
|
|
||||||
|
@NonNull private LottieAnimationView mAodFp;
|
||||||
|
|
||||||
@NonNull private final AnimatedVectorDrawable mFpToUnlockIcon;
|
@NonNull private final AnimatedVectorDrawable mFpToUnlockIcon;
|
||||||
@NonNull private final AnimatedVectorDrawable mLockToUnlockIcon;
|
@NonNull private final AnimatedVectorDrawable mLockToUnlockIcon;
|
||||||
@NonNull private final Drawable mLockIcon;
|
@NonNull private final Drawable mLockIcon;
|
||||||
@@ -109,6 +116,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
|||||||
private boolean mIsKeyguardShowing;
|
private boolean mIsKeyguardShowing;
|
||||||
private boolean mUserUnlockedWithBiometric;
|
private boolean mUserUnlockedWithBiometric;
|
||||||
private Runnable mCancelDelayedUpdateVisibilityRunnable;
|
private Runnable mCancelDelayedUpdateVisibilityRunnable;
|
||||||
|
private Runnable mOnGestureDetectedRunnable;
|
||||||
|
|
||||||
private boolean mUdfpsSupported;
|
private boolean mUdfpsSupported;
|
||||||
private float mHeightPixels;
|
private float mHeightPixels;
|
||||||
@@ -118,6 +126,12 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
|||||||
private boolean mShowUnlockIcon;
|
private boolean mShowUnlockIcon;
|
||||||
private boolean mShowLockIcon;
|
private boolean mShowLockIcon;
|
||||||
|
|
||||||
|
// for udfps when strong auth is required or unlocked on AOD
|
||||||
|
private boolean mShowAODFpIcon;
|
||||||
|
private final int mMaxBurnInOffsetX;
|
||||||
|
private final int mMaxBurnInOffsetY;
|
||||||
|
private float mInterpolatedDarkAmount;
|
||||||
|
|
||||||
private boolean mDownDetected;
|
private boolean mDownDetected;
|
||||||
private boolean mDetectedLongPress;
|
private boolean mDetectedLongPress;
|
||||||
private final Rect mSensorTouchLocation = new Rect();
|
private final Rect mSensorTouchLocation = new Rect();
|
||||||
@@ -150,6 +164,12 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
|||||||
mVibrator = vibrator;
|
mVibrator = vibrator;
|
||||||
|
|
||||||
final Context context = view.getContext();
|
final Context context = view.getContext();
|
||||||
|
mAodFp = mView.findViewById(R.id.lock_udfps_aod_fp);
|
||||||
|
mMaxBurnInOffsetX = context.getResources()
|
||||||
|
.getDimensionPixelSize(R.dimen.udfps_burn_in_offset_x);
|
||||||
|
mMaxBurnInOffsetY = context.getResources()
|
||||||
|
.getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y);
|
||||||
|
|
||||||
mUnlockIcon = mView.getContext().getResources().getDrawable(
|
mUnlockIcon = mView.getContext().getResources().getDrawable(
|
||||||
R.drawable.ic_unlock,
|
R.drawable.ic_unlock,
|
||||||
mView.getContext().getTheme());
|
mView.getContext().getTheme());
|
||||||
@@ -173,15 +193,14 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onViewAttached() {
|
protected void onViewAttached() {
|
||||||
// we check this here instead of onInit since the FingerprintManager + FaceManager may not
|
updateIsUdfpsEnrolled();
|
||||||
// have started up yet onInit
|
|
||||||
mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null;
|
|
||||||
|
|
||||||
updateConfiguration();
|
updateConfiguration();
|
||||||
updateKeyguardShowing();
|
updateKeyguardShowing();
|
||||||
mUserUnlockedWithBiometric = false;
|
mUserUnlockedWithBiometric = false;
|
||||||
|
|
||||||
mIsBouncerShowing = mKeyguardViewController.isBouncerShowing();
|
mIsBouncerShowing = mKeyguardViewController.isBouncerShowing();
|
||||||
mIsDozing = mStatusBarStateController.isDozing();
|
mIsDozing = mStatusBarStateController.isDozing();
|
||||||
|
mInterpolatedDarkAmount = mStatusBarStateController.getDozeAmount();
|
||||||
mRunningFPS = mKeyguardUpdateMonitor.isFingerprintDetectionRunning();
|
mRunningFPS = mKeyguardUpdateMonitor.isFingerprintDetectionRunning();
|
||||||
mCanDismissLockScreen = mKeyguardStateController.canDismissLockScreen();
|
mCanDismissLockScreen = mKeyguardStateController.canDismissLockScreen();
|
||||||
mStatusBarState = mStatusBarStateController.getState();
|
mStatusBarState = mStatusBarStateController.getState();
|
||||||
@@ -189,15 +208,18 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
|||||||
updateColors();
|
updateColors();
|
||||||
mConfigurationController.addCallback(mConfigurationListener);
|
mConfigurationController.addCallback(mConfigurationListener);
|
||||||
|
|
||||||
|
mAuthController.addCallback(mAuthControllerCallback);
|
||||||
mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
|
mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
|
||||||
mStatusBarStateController.addCallback(mStatusBarStateListener);
|
mStatusBarStateController.addCallback(mStatusBarStateListener);
|
||||||
mKeyguardStateController.addCallback(mKeyguardStateCallback);
|
mKeyguardStateController.addCallback(mKeyguardStateCallback);
|
||||||
mDownDetected = false;
|
mDownDetected = false;
|
||||||
|
updateBurnInOffsets();
|
||||||
updateVisibility();
|
updateVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onViewDetached() {
|
protected void onViewDetached() {
|
||||||
|
mAuthController.removeCallback(mAuthControllerCallback);
|
||||||
mConfigurationController.removeCallback(mConfigurationListener);
|
mConfigurationController.removeCallback(mConfigurationListener);
|
||||||
mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback);
|
mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback);
|
||||||
mStatusBarStateController.removeCallback(mStatusBarStateListener);
|
mStatusBarStateController.removeCallback(mStatusBarStateListener);
|
||||||
@@ -227,7 +249,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
|||||||
mCancelDelayedUpdateVisibilityRunnable = null;
|
mCancelDelayedUpdateVisibilityRunnable = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mIsKeyguardShowing) {
|
if (!mIsKeyguardShowing && !mIsDozing) {
|
||||||
mView.setVisibility(View.INVISIBLE);
|
mView.setVisibility(View.INVISIBLE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -238,6 +260,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
|||||||
mShowLockIcon = !mCanDismissLockScreen && !mUserUnlockedWithBiometric && isLockScreen()
|
mShowLockIcon = !mCanDismissLockScreen && !mUserUnlockedWithBiometric && isLockScreen()
|
||||||
&& (!mUdfpsEnrolled || !mRunningFPS);
|
&& (!mUdfpsEnrolled || !mRunningFPS);
|
||||||
mShowUnlockIcon = mCanDismissLockScreen && isLockScreen();
|
mShowUnlockIcon = mCanDismissLockScreen && isLockScreen();
|
||||||
|
mShowAODFpIcon = mIsDozing && mUdfpsEnrolled && !mRunningFPS;
|
||||||
|
|
||||||
final CharSequence prevContentDescription = mView.getContentDescription();
|
final CharSequence prevContentDescription = mView.getContentDescription();
|
||||||
if (mShowLockIcon) {
|
if (mShowLockIcon) {
|
||||||
@@ -260,10 +283,22 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
|||||||
}
|
}
|
||||||
mView.setVisibility(View.VISIBLE);
|
mView.setVisibility(View.VISIBLE);
|
||||||
mView.setContentDescription(mUnlockedLabel);
|
mView.setContentDescription(mUnlockedLabel);
|
||||||
|
} else if (mShowAODFpIcon) {
|
||||||
|
mView.setImageDrawable(null);
|
||||||
|
mView.setContentDescription(null);
|
||||||
|
mAodFp.setVisibility(View.VISIBLE);
|
||||||
|
mAodFp.setContentDescription(mCanDismissLockScreen ? mUnlockedLabel : mLockedLabel);
|
||||||
|
mView.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
mView.setVisibility(View.INVISIBLE);
|
mView.setVisibility(View.INVISIBLE);
|
||||||
mView.setContentDescription(null);
|
mView.setContentDescription(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mShowAODFpIcon) {
|
||||||
|
mAodFp.setVisibility(View.INVISIBLE);
|
||||||
|
mAodFp.setContentDescription(null);
|
||||||
|
}
|
||||||
|
|
||||||
if (!Objects.equals(prevContentDescription, mView.getContentDescription())
|
if (!Objects.equals(prevContentDescription, mView.getContentDescription())
|
||||||
&& mView.getContentDescription() != null) {
|
&& mView.getContentDescription() != null) {
|
||||||
mView.announceForAccessibility(mView.getContentDescription());
|
mView.announceForAccessibility(mView.getContentDescription());
|
||||||
@@ -340,10 +375,12 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
|
public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
|
||||||
|
pw.println("mUdfpsSupported: " + mUdfpsSupported);
|
||||||
pw.println("mUdfpsEnrolled: " + mUdfpsEnrolled);
|
pw.println("mUdfpsEnrolled: " + mUdfpsEnrolled);
|
||||||
pw.println("mIsKeyguardShowing: " + mIsKeyguardShowing);
|
pw.println("mIsKeyguardShowing: " + mIsKeyguardShowing);
|
||||||
pw.println(" mShowUnlockIcon: " + mShowUnlockIcon);
|
pw.println(" mShowUnlockIcon: " + mShowUnlockIcon);
|
||||||
pw.println(" mShowLockIcon: " + mShowLockIcon);
|
pw.println(" mShowLockIcon: " + mShowLockIcon);
|
||||||
|
pw.println(" mShowAODFpIcon: " + mShowAODFpIcon);
|
||||||
pw.println(" mIsDozing: " + mIsDozing);
|
pw.println(" mIsDozing: " + mIsDozing);
|
||||||
pw.println(" mIsBouncerShowing: " + mIsBouncerShowing);
|
pw.println(" mIsBouncerShowing: " + mIsBouncerShowing);
|
||||||
pw.println(" mUserUnlockedWithBiometric: " + mUserUnlockedWithBiometric);
|
pw.println(" mUserUnlockedWithBiometric: " + mUserUnlockedWithBiometric);
|
||||||
@@ -351,17 +388,57 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
|||||||
pw.println(" mCanDismissLockScreen: " + mCanDismissLockScreen);
|
pw.println(" mCanDismissLockScreen: " + mCanDismissLockScreen);
|
||||||
pw.println(" mStatusBarState: " + StatusBarState.toShortString(mStatusBarState));
|
pw.println(" mStatusBarState: " + StatusBarState.toShortString(mStatusBarState));
|
||||||
pw.println(" mQsExpanded: " + mQsExpanded);
|
pw.println(" mQsExpanded: " + mQsExpanded);
|
||||||
|
pw.println(" mInterpolatedDarkAmount: " + mInterpolatedDarkAmount);
|
||||||
|
|
||||||
if (mView != null) {
|
if (mView != null) {
|
||||||
mView.dump(fd, pw, args);
|
mView.dump(fd, pw, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Every minute, update the aod icon's burn in offset */
|
||||||
|
public void dozeTimeTick() {
|
||||||
|
updateBurnInOffsets();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateBurnInOffsets() {
|
||||||
|
float offsetX = MathUtils.lerp(0f,
|
||||||
|
getBurnInOffset(mMaxBurnInOffsetX * 2, true /* xAxis */)
|
||||||
|
- mMaxBurnInOffsetX, mInterpolatedDarkAmount);
|
||||||
|
float offsetY = MathUtils.lerp(0f,
|
||||||
|
getBurnInOffset(mMaxBurnInOffsetY * 2, false /* xAxis */)
|
||||||
|
- mMaxBurnInOffsetY, mInterpolatedDarkAmount);
|
||||||
|
float progress = MathUtils.lerp(0f, getBurnInProgressOffset(), mInterpolatedDarkAmount);
|
||||||
|
|
||||||
|
mAodFp.setTranslationX(offsetX);
|
||||||
|
mAodFp.setTranslationY(offsetY);
|
||||||
|
mAodFp.setProgress(progress);
|
||||||
|
mAodFp.setAlpha(255 * mInterpolatedDarkAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateIsUdfpsEnrolled() {
|
||||||
|
boolean wasUdfpsSupported = mUdfpsSupported;
|
||||||
|
boolean wasUdfpsEnrolled = mUdfpsEnrolled;
|
||||||
|
|
||||||
|
mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null;
|
||||||
|
mUdfpsEnrolled = mKeyguardUpdateMonitor.isUdfpsEnrolled();
|
||||||
|
if (wasUdfpsSupported != mUdfpsSupported || wasUdfpsEnrolled != mUdfpsEnrolled) {
|
||||||
|
updateVisibility();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private StatusBarStateController.StateListener mStatusBarStateListener =
|
private StatusBarStateController.StateListener mStatusBarStateListener =
|
||||||
new StatusBarStateController.StateListener() {
|
new StatusBarStateController.StateListener() {
|
||||||
|
@Override
|
||||||
|
public void onDozeAmountChanged(float linear, float eased) {
|
||||||
|
mInterpolatedDarkAmount = eased;
|
||||||
|
updateBurnInOffsets();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDozingChanged(boolean isDozing) {
|
public void onDozingChanged(boolean isDozing) {
|
||||||
mIsDozing = isDozing;
|
mIsDozing = isDozing;
|
||||||
|
updateBurnInOffsets();
|
||||||
|
updateIsUdfpsEnrolled();
|
||||||
updateVisibility();
|
updateVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -435,7 +512,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
|||||||
mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(
|
mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(
|
||||||
KeyguardUpdateMonitor.getCurrentUser());
|
KeyguardUpdateMonitor.getCurrentUser());
|
||||||
}
|
}
|
||||||
mUdfpsEnrolled = mKeyguardUpdateMonitor.isUdfpsEnrolled();
|
updateIsUdfpsEnrolled();
|
||||||
updateVisibility();
|
updateVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,8 +558,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
|||||||
|
|
||||||
// intercept all following touches until we see MotionEvent.ACTION_CANCEL UP or
|
// intercept all following touches until we see MotionEvent.ACTION_CANCEL UP or
|
||||||
// MotionEvent.ACTION_UP (see #onTouchEvent)
|
// MotionEvent.ACTION_UP (see #onTouchEvent)
|
||||||
mDownDetected = true;
|
if (mVibrator != null && !mDownDetected) {
|
||||||
if (mVibrator != null) {
|
|
||||||
mVibrator.vibrate(
|
mVibrator.vibrate(
|
||||||
Process.myUid(),
|
Process.myUid(),
|
||||||
getContext().getOpPackageName(),
|
getContext().getOpPackageName(),
|
||||||
@@ -490,6 +566,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
|||||||
"lockIcon-onDown",
|
"lockIcon-onDown",
|
||||||
VIBRATION_SONIFICATION_ATTRIBUTES);
|
VIBRATION_SONIFICATION_ATTRIBUTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mDownDetected = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,6 +622,9 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
|||||||
// pre-emptively set to true to hide view
|
// pre-emptively set to true to hide view
|
||||||
mIsBouncerShowing = true;
|
mIsBouncerShowing = true;
|
||||||
updateVisibility();
|
updateVisibility();
|
||||||
|
if (mOnGestureDetectedRunnable != null) {
|
||||||
|
mOnGestureDetectedRunnable.run();
|
||||||
|
}
|
||||||
mKeyguardViewController.showBouncer(/* scrim */ true);
|
mKeyguardViewController.showBouncer(/* scrim */ true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -554,16 +635,18 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
|||||||
* in a 'clickable' state
|
* in a 'clickable' state
|
||||||
* @return whether to intercept the touch event
|
* @return whether to intercept the touch event
|
||||||
*/
|
*/
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
public boolean onTouchEvent(MotionEvent event, Runnable onGestureDetectedRunnable) {
|
||||||
if (mSensorTouchLocation.contains((int) event.getX(), (int) event.getY())
|
if (mSensorTouchLocation.contains((int) event.getX(), (int) event.getY())
|
||||||
&& mView.getVisibility() == View.VISIBLE) {
|
&& (mView.getVisibility() == View.VISIBLE
|
||||||
|
|| mAodFp.getVisibility() == View.VISIBLE)) {
|
||||||
|
mOnGestureDetectedRunnable = onGestureDetectedRunnable;
|
||||||
mGestureDetector.onTouchEvent(event);
|
mGestureDetector.onTouchEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// we continue to intercept all following touches until we see MotionEvent.ACTION_CANCEL UP
|
// we continue to intercept all following touches until we see MotionEvent.ACTION_CANCEL UP
|
||||||
// or MotionEvent.ACTION_UP. this is to avoid passing the touch to NPV
|
// or MotionEvent.ACTION_UP. this is to avoid passing the touch to NPV
|
||||||
// after the lock icon disappears on device entry
|
// after the lock icon disappears on device entry
|
||||||
if (mDownDetected && mDetectedLongPress) {
|
if (mDownDetected) {
|
||||||
if (event.getAction() == MotionEvent.ACTION_CANCEL
|
if (event.getAction() == MotionEvent.ACTION_CANCEL
|
||||||
|| event.getAction() == MotionEvent.ACTION_UP) {
|
|| event.getAction() == MotionEvent.ACTION_UP) {
|
||||||
mDownDetected = false;
|
mDownDetected = false;
|
||||||
@@ -583,4 +666,12 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
|||||||
public void setAlpha(float alpha) {
|
public void setAlpha(float alpha) {
|
||||||
mView.setAlpha(alpha);
|
mView.setAlpha(alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() {
|
||||||
|
@Override
|
||||||
|
public void onAllAuthenticatorsRegistered() {
|
||||||
|
updateIsUdfpsEnrolled();
|
||||||
|
updateConfiguration();
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -848,6 +848,10 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mAodInterruptRunnable = () -> {
|
mAodInterruptRunnable = () -> {
|
||||||
mIsAodInterruptActive = true;
|
mIsAodInterruptActive = true;
|
||||||
// Since the sensor that triggers the AOD interrupt doesn't provide
|
// Since the sensor that triggers the AOD interrupt doesn't provide
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ import com.android.systemui.util.concurrency.DelayableExecutor;
|
|||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class that coordinates non-HBM animations during keyguard authentication.
|
* Class that coordinates non-HBM animations during keyguard authentication.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -3655,6 +3655,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void dozeTimeTick() {
|
public void dozeTimeTick() {
|
||||||
|
mLockIconViewController.dozeTimeTick();
|
||||||
mKeyguardBottomArea.dozeTimeTick();
|
mKeyguardBottomArea.dozeTimeTick();
|
||||||
mKeyguardStatusViewController.dozeTimeTick();
|
mKeyguardStatusViewController.dozeTimeTick();
|
||||||
if (mInterpolatedDarkAmount > 0) {
|
if (mInterpolatedDarkAmount > 0) {
|
||||||
@@ -3958,10 +3959,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
mStatusBarKeyguardViewManager.updateKeyguardPosition(event.getX());
|
mStatusBarKeyguardViewManager.updateKeyguardPosition(event.getX());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mLockIconViewController.onTouchEvent(event)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
handled |= super.onTouch(v, event);
|
handled |= super.onTouch(v, event);
|
||||||
return !mDozing || mPulsing || handled;
|
return !mDozing || mPulsing || handled;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
import com.android.keyguard.LockIconViewController;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.classifier.FalsingCollector;
|
import com.android.systemui.classifier.FalsingCollector;
|
||||||
import com.android.systemui.dock.DockManager;
|
import com.android.systemui.dock.DockManager;
|
||||||
@@ -88,6 +89,7 @@ public class NotificationShadeWindowViewController {
|
|||||||
private final NotificationShadeDepthController mDepthController;
|
private final NotificationShadeDepthController mDepthController;
|
||||||
private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
|
private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
|
||||||
private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
|
private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
|
||||||
|
private final LockIconViewController mLockIconViewController;
|
||||||
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
||||||
|
|
||||||
private GestureDetector mGestureDetector;
|
private GestureDetector mGestureDetector;
|
||||||
@@ -138,7 +140,8 @@ public class NotificationShadeWindowViewController {
|
|||||||
NotificationPanelViewController notificationPanelViewController,
|
NotificationPanelViewController notificationPanelViewController,
|
||||||
SuperStatusBarViewFactory statusBarViewFactory,
|
SuperStatusBarViewFactory statusBarViewFactory,
|
||||||
NotificationStackScrollLayoutController notificationStackScrollLayoutController,
|
NotificationStackScrollLayoutController notificationStackScrollLayoutController,
|
||||||
StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
|
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
|
||||||
|
LockIconViewController lockIconViewController) {
|
||||||
mInjectionInflationController = injectionInflationController;
|
mInjectionInflationController = injectionInflationController;
|
||||||
mCoordinator = coordinator;
|
mCoordinator = coordinator;
|
||||||
mPulseExpansionHandler = pulseExpansionHandler;
|
mPulseExpansionHandler = pulseExpansionHandler;
|
||||||
@@ -163,6 +166,7 @@ public class NotificationShadeWindowViewController {
|
|||||||
mStatusBarViewFactory = statusBarViewFactory;
|
mStatusBarViewFactory = statusBarViewFactory;
|
||||||
mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
|
mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
|
||||||
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
|
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
|
||||||
|
mLockIconViewController = lockIconViewController;
|
||||||
|
|
||||||
// This view is not part of the newly inflated expanded status bar.
|
// This view is not part of the newly inflated expanded status bar.
|
||||||
mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container);
|
mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container);
|
||||||
@@ -235,6 +239,7 @@ public class NotificationShadeWindowViewController {
|
|||||||
if (!isCancel && mService.shouldIgnoreTouch()) {
|
if (!isCancel && mService.shouldIgnoreTouch()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDown) {
|
if (isDown) {
|
||||||
setTouchActive(true);
|
setTouchActive(true);
|
||||||
mTouchCancelled = false;
|
mTouchCancelled = false;
|
||||||
@@ -245,6 +250,7 @@ public class NotificationShadeWindowViewController {
|
|||||||
if (mTouchCancelled || mExpandAnimationRunning) {
|
if (mTouchCancelled || mExpandAnimationRunning) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mFalsingCollector.onTouchEvent(ev);
|
mFalsingCollector.onTouchEvent(ev);
|
||||||
mGestureDetector.onTouchEvent(ev);
|
mGestureDetector.onTouchEvent(ev);
|
||||||
mStatusBarKeyguardViewManager.onTouch(ev);
|
mStatusBarKeyguardViewManager.onTouch(ev);
|
||||||
@@ -260,9 +266,17 @@ public class NotificationShadeWindowViewController {
|
|||||||
if (isDown) {
|
if (isDown) {
|
||||||
mNotificationStackScrollLayoutController.closeControlsIfOutsideTouch(ev);
|
mNotificationStackScrollLayoutController.closeControlsIfOutsideTouch(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mStatusBarStateController.isDozing()) {
|
if (mStatusBarStateController.isDozing()) {
|
||||||
mService.mDozeScrimController.extendPulse();
|
mService.mDozeScrimController.extendPulse();
|
||||||
}
|
}
|
||||||
|
mLockIconViewController.onTouchEvent(
|
||||||
|
ev,
|
||||||
|
() -> mService.wakeUpIfDozing(
|
||||||
|
SystemClock.uptimeMillis(),
|
||||||
|
mView,
|
||||||
|
"LOCK_ICON_TOUCH"));
|
||||||
|
|
||||||
// In case we start outside of the view bounds (below the status bar), we need to
|
// In case we start outside of the view bounds (below the status bar), we need to
|
||||||
// dispatch
|
// dispatch
|
||||||
// the touch manually as the view system can't accommodate for touches outside of
|
// the touch manually as the view system can't accommodate for touches outside of
|
||||||
|
|||||||
@@ -456,11 +456,12 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void aodInterrupt() throws RemoteException {
|
public void aodInterrupt() throws RemoteException {
|
||||||
// GIVEN that the overlay is showing and screen is on
|
// GIVEN that the overlay is showing and screen is on and fp is running
|
||||||
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
|
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
|
||||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
|
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
|
||||||
mScreenObserver.onScreenTurnedOn();
|
mScreenObserver.onScreenTurnedOn();
|
||||||
mFgExecutor.runAllReady();
|
mFgExecutor.runAllReady();
|
||||||
|
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
|
||||||
// WHEN fingerprint is requested because of AOD interrupt
|
// WHEN fingerprint is requested because of AOD interrupt
|
||||||
mUdfpsController.onAodInterrupt(0, 0, 2f, 3f);
|
mUdfpsController.onAodInterrupt(0, 0, 2f, 3f);
|
||||||
// THEN illumination begins
|
// THEN illumination begins
|
||||||
@@ -478,6 +479,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
|||||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
|
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
|
||||||
mScreenObserver.onScreenTurnedOn();
|
mScreenObserver.onScreenTurnedOn();
|
||||||
mFgExecutor.runAllReady();
|
mFgExecutor.runAllReady();
|
||||||
|
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
|
||||||
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
|
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
|
||||||
when(mUdfpsView.isIlluminationRequested()).thenReturn(true);
|
when(mUdfpsView.isIlluminationRequested()).thenReturn(true);
|
||||||
// WHEN it is cancelled
|
// WHEN it is cancelled
|
||||||
@@ -493,6 +495,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
|||||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
|
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
|
||||||
mScreenObserver.onScreenTurnedOn();
|
mScreenObserver.onScreenTurnedOn();
|
||||||
mFgExecutor.runAllReady();
|
mFgExecutor.runAllReady();
|
||||||
|
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
|
||||||
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
|
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
|
||||||
when(mUdfpsView.isIlluminationRequested()).thenReturn(true);
|
when(mUdfpsView.isIlluminationRequested()).thenReturn(true);
|
||||||
// WHEN it times out
|
// WHEN it times out
|
||||||
@@ -511,6 +514,23 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
|||||||
mFgExecutor.runAllReady();
|
mFgExecutor.runAllReady();
|
||||||
|
|
||||||
// WHEN aod interrupt is received
|
// WHEN aod interrupt is received
|
||||||
|
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
|
||||||
|
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
|
||||||
|
|
||||||
|
// THEN no illumination because screen is off
|
||||||
|
verify(mUdfpsView, never()).startIllumination(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void aodInterrupt_fingerprintNotRunning() throws RemoteException {
|
||||||
|
// GIVEN showing overlay
|
||||||
|
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
|
||||||
|
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
|
||||||
|
mScreenObserver.onScreenTurnedOn();
|
||||||
|
mFgExecutor.runAllReady();
|
||||||
|
|
||||||
|
// WHEN aod interrupt is received when the fingerprint service isn't running
|
||||||
|
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(false);
|
||||||
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
|
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
|
||||||
|
|
||||||
// THEN no illumination because screen is off
|
// THEN no illumination because screen is off
|
||||||
|
|||||||
@@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.keyguard;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.anyInt;
|
||||||
|
import static org.mockito.Mockito.eq;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.graphics.PointF;
|
||||||
|
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||||
|
import android.os.Vibrator;
|
||||||
|
import android.testing.AndroidTestingRunner;
|
||||||
|
import android.testing.TestableLooper;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.accessibility.AccessibilityManager;
|
||||||
|
|
||||||
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
|
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||||
|
import com.android.keyguard.KeyguardViewController;
|
||||||
|
import com.android.keyguard.LockIconView;
|
||||||
|
import com.android.keyguard.LockIconViewController;
|
||||||
|
import com.android.systemui.SysuiTestCase;
|
||||||
|
import com.android.systemui.biometrics.AuthController;
|
||||||
|
import com.android.systemui.biometrics.AuthRippleController;
|
||||||
|
import com.android.systemui.dump.DumpManager;
|
||||||
|
import com.android.systemui.plugins.FalsingManager;
|
||||||
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
|
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||||
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
|
import com.android.systemui.util.concurrency.DelayableExecutor;
|
||||||
|
|
||||||
|
import com.airbnb.lottie.LottieAnimationView;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Captor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
@RunWith(AndroidTestingRunner.class)
|
||||||
|
@TestableLooper.RunWithLooper
|
||||||
|
public class LockIconViewControllerTest extends SysuiTestCase {
|
||||||
|
private @Mock LockIconView mLockIconView;
|
||||||
|
private @Mock Context mContext;
|
||||||
|
private @Mock Resources mResources;
|
||||||
|
private @Mock DisplayMetrics mDisplayMetrics;
|
||||||
|
private @Mock StatusBarStateController mStatusBarStateController;
|
||||||
|
private @Mock KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||||
|
private @Mock KeyguardViewController mKeyguardViewController;
|
||||||
|
private @Mock KeyguardStateController mKeyguardStateController;
|
||||||
|
private @Mock FalsingManager mFalsingManager;
|
||||||
|
private @Mock AuthController mAuthController;
|
||||||
|
private @Mock DumpManager mDumpManager;
|
||||||
|
private @Mock AccessibilityManager mAccessibilityManager;
|
||||||
|
private @Mock ConfigurationController mConfigurationController;
|
||||||
|
private @Mock DelayableExecutor mDelayableExecutor;
|
||||||
|
private @Mock Vibrator mVibrator;
|
||||||
|
private @Mock AuthRippleController mAuthRippleController;
|
||||||
|
private @Mock LottieAnimationView mAodFp;
|
||||||
|
|
||||||
|
private LockIconViewController mLockIconViewController;
|
||||||
|
|
||||||
|
// Capture listeners so that they can be used to send events
|
||||||
|
@Captor private ArgumentCaptor<View.OnAttachStateChangeListener> mAttachCaptor =
|
||||||
|
ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
|
||||||
|
private View.OnAttachStateChangeListener mAttachListener;
|
||||||
|
|
||||||
|
@Captor private ArgumentCaptor<AuthController.Callback> mAuthControllerCallbackCaptor;
|
||||||
|
private AuthController.Callback mAuthControllerCallback;
|
||||||
|
|
||||||
|
@Captor private ArgumentCaptor<PointF> mPointCaptor;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
when(mLockIconView.getResources()).thenReturn(mResources);
|
||||||
|
when(mLockIconView.getContext()).thenReturn(mContext);
|
||||||
|
when(mContext.getResources()).thenReturn(mResources);
|
||||||
|
when(mResources.getDisplayMetrics()).thenReturn(mDisplayMetrics);
|
||||||
|
when(mLockIconView.findViewById(anyInt())).thenReturn(mAodFp);
|
||||||
|
|
||||||
|
mLockIconViewController = new LockIconViewController(
|
||||||
|
mLockIconView,
|
||||||
|
mStatusBarStateController,
|
||||||
|
mKeyguardUpdateMonitor,
|
||||||
|
mKeyguardViewController,
|
||||||
|
mKeyguardStateController,
|
||||||
|
mFalsingManager,
|
||||||
|
mAuthController,
|
||||||
|
mDumpManager,
|
||||||
|
mAccessibilityManager,
|
||||||
|
mConfigurationController,
|
||||||
|
mDelayableExecutor,
|
||||||
|
mVibrator
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateFingerprintLocationOnInit() {
|
||||||
|
// GIVEN fp sensor location is available pre-attached
|
||||||
|
final PointF udfpsLocation = new PointF(50, 75);
|
||||||
|
final int radius = 33;
|
||||||
|
final FingerprintSensorPropertiesInternal fpProps =
|
||||||
|
new FingerprintSensorPropertiesInternal(
|
||||||
|
/* sensorId */ 0,
|
||||||
|
/* strength */ 0,
|
||||||
|
/* max enrollments per user */ 5,
|
||||||
|
/* component info */ new ArrayList<>(),
|
||||||
|
/* sensorType */ 3,
|
||||||
|
/* resetLockoutRequiresHwToken */ false,
|
||||||
|
(int) udfpsLocation.x, (int) udfpsLocation.y, radius);
|
||||||
|
when(mAuthController.getUdfpsSensorLocation()).thenReturn(udfpsLocation);
|
||||||
|
when(mAuthController.getUdfpsProps()).thenReturn(List.of(fpProps));
|
||||||
|
|
||||||
|
// WHEN lock icon view controller is initialized and attached
|
||||||
|
mLockIconViewController.init();
|
||||||
|
captureAttachListener();
|
||||||
|
mAttachListener.onViewAttachedToWindow(mLockIconView);
|
||||||
|
|
||||||
|
// THEN lock icon view location is updated with the same coordinates as fpProps
|
||||||
|
verify(mLockIconView).setCenterLocation(mPointCaptor.capture(), eq(radius));
|
||||||
|
assertEquals(udfpsLocation, mPointCaptor.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateFingerprintLocationOnAuthenticatorsRegistered() {
|
||||||
|
// GIVEN fp sensor location is not available pre-init
|
||||||
|
when(mAuthController.getFingerprintSensorLocation()).thenReturn(null);
|
||||||
|
when(mAuthController.getUdfpsProps()).thenReturn(null);
|
||||||
|
mLockIconViewController.init();
|
||||||
|
captureAttachListener();
|
||||||
|
mAttachListener.onViewAttachedToWindow(mLockIconView);
|
||||||
|
|
||||||
|
// GIVEN fp sensor location is available post-atttached
|
||||||
|
captureAuthControllerCallback();
|
||||||
|
final PointF udfpsLocation = new PointF(50, 75);
|
||||||
|
final int radius = 33;
|
||||||
|
final FingerprintSensorPropertiesInternal fpProps =
|
||||||
|
new FingerprintSensorPropertiesInternal(
|
||||||
|
/* sensorId */ 0,
|
||||||
|
/* strength */ 0,
|
||||||
|
/* max enrollments per user */ 5,
|
||||||
|
/* component info */ new ArrayList<>(),
|
||||||
|
/* sensorType */ 3,
|
||||||
|
/* resetLockoutRequiresHwToken */ false,
|
||||||
|
(int) udfpsLocation.x, (int) udfpsLocation.y, radius);
|
||||||
|
when(mAuthController.getUdfpsSensorLocation()).thenReturn(udfpsLocation);
|
||||||
|
when(mAuthController.getUdfpsProps()).thenReturn(List.of(fpProps));
|
||||||
|
|
||||||
|
// WHEN all authenticators are registered
|
||||||
|
mAuthControllerCallback.onAllAuthenticatorsRegistered();
|
||||||
|
|
||||||
|
// THEN lock icon view location is updated with the same coordinates as fpProps
|
||||||
|
verify(mLockIconView).setCenterLocation(mPointCaptor.capture(), eq(radius));
|
||||||
|
assertEquals(udfpsLocation, mPointCaptor.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void captureAuthControllerCallback() {
|
||||||
|
verify(mAuthController).addCallback(mAuthControllerCallbackCaptor.capture());
|
||||||
|
mAuthControllerCallback = mAuthControllerCallbackCaptor.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void captureAttachListener() {
|
||||||
|
verify(mLockIconView).addOnAttachStateChangeListener(mAttachCaptor.capture());
|
||||||
|
mAttachListener = mAttachCaptor.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,6 +27,7 @@ import android.view.MotionEvent;
|
|||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
|
import com.android.keyguard.LockIconViewController;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.SystemUIFactory;
|
import com.android.systemui.SystemUIFactory;
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
@@ -90,6 +91,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
|
|||||||
@Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
|
@Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
|
||||||
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
||||||
@Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
|
@Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
|
||||||
|
@Mock private LockIconViewController mLockIconViewController;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
@@ -131,7 +133,8 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
|
|||||||
mNotificationPanelViewController,
|
mNotificationPanelViewController,
|
||||||
mStatusBarViewFactory,
|
mStatusBarViewFactory,
|
||||||
mNotificationStackScrollLayoutController,
|
mNotificationStackScrollLayoutController,
|
||||||
mStatusBarKeyguardViewManager);
|
mStatusBarKeyguardViewManager,
|
||||||
|
mLockIconViewController);
|
||||||
mController.setupExpandedStatusBar();
|
mController.setupExpandedStatusBar();
|
||||||
mController.setService(mStatusBar, mNotificationShadeWindowController);
|
mController.setService(mStatusBar, mNotificationShadeWindowController);
|
||||||
mController.setDragDownHelper(mDragDownHelper);
|
mController.setDragDownHelper(mDragDownHelper);
|
||||||
|
|||||||
Reference in New Issue
Block a user