summaryrefslogtreecommitdiff
path: root/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
diff options
context:
space:
mode:
authorHaamed Gheibi <haamed@google.com>2021-07-12 20:47:45 +0000
committerHaamed Gheibi <haamed@google.com>2021-07-14 18:21:17 +0000
commit02a7ee5d65cb8d40fd1dde9aaf6b5ead9222a5a6 (patch)
tree6fb30a5bc0d0e7fadd37d62cdba537c4d5d9237b /packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
parentbab7c6ab6b363574baaace4df576c1abb67f4507 (diff)
parentfa0439912edd9559d7c0f46bef2b2898de68f50f (diff)
Merge SP1A.210709.002
Change-Id: I4610885d5d770d858895057cdd9fea387a5e33dd
Diffstat (limited to 'packages/SystemUI/src/com/android/keyguard/LockIconViewController.java')
-rw-r--r--packages/SystemUI/src/com/android/keyguard/LockIconViewController.java241
1 files changed, 145 insertions, 96 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index ccc487925fe4..62cb4b9a33f5 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -18,17 +18,21 @@ package com.android.keyguard;
import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
-import static com.android.systemui.classifier.Classifier.DISABLED_UDFPS_AFFORDANCE;
+import static com.android.systemui.classifier.Classifier.LOCK_ICON;
import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.PointF;
+import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.InsetDrawable;
import android.hardware.biometrics.BiometricSourceType;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
-import android.util.Log;
+import android.util.DisplayMetrics;
+import android.view.GestureDetector;
+import android.view.GestureDetector.SimpleOnGestureListener;
+import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -73,15 +77,10 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
@NonNull private final AccessibilityManager mAccessibilityManager;
@NonNull private final ConfigurationController mConfigurationController;
@NonNull private final DelayableExecutor mExecutor;
-
- private boolean mHasUdfpsOrFaceAuthFeatures;
private boolean mUdfpsEnrolled;
- private boolean mFaceAuthEnrolled;
- @NonNull private final Drawable mButton;
@NonNull private final Drawable mUnlockIcon;
@NonNull private final Drawable mLockIcon;
- @NonNull private final CharSequence mDisabledLabel;
@NonNull private final CharSequence mUnlockedLabel;
@NonNull private final CharSequence mLockedLabel;
@@ -95,10 +94,18 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
private boolean mUserUnlockedWithBiometric;
private Runnable mCancelDelayedUpdateVisibilityRunnable;
- private boolean mShowButton;
+ private boolean mHasUdfps;
+ private float mHeightPixels;
+ private float mWidthPixels;
+ private float mDensity;
+ private int mKgBottomAreaHeight;
+
private boolean mShowUnlockIcon;
private boolean mShowLockIcon;
+ private boolean mDownDetected;
+ private final Rect mSensorTouchLocation = new Rect();
+
@Inject
public LockIconViewController(
@Nullable LockIconView view,
@@ -125,8 +132,6 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
mExecutor = executor;
final Context context = view.getContext();
- mButton = context.getResources().getDrawable(
- com.android.systemui.R.drawable.circle_white, context.getTheme());
mUnlockIcon = new InsetDrawable(context.getResources().getDrawable(
com.android.internal.R.drawable.ic_lock_open, context.getTheme()),
context.getResources().getDimensionPixelSize(
@@ -135,8 +140,6 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
com.android.internal.R.drawable.ic_lock, context.getTheme()),
context.getResources().getDimensionPixelSize(
com.android.systemui.R.dimen.udfps_unlock_icon_inset));
- mDisabledLabel = context.getResources().getString(
- R.string.accessibility_udfps_disabled_button);
mUnlockedLabel = context.getResources().getString(R.string.accessibility_unlock_button);
mLockedLabel = context.getResources().getString(R.string.accessibility_lock_icon);
dumpManager.registerDumpable("LockIconViewController", this);
@@ -149,37 +152,11 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
@Override
protected void onViewAttached() {
- // we check this here instead of onInit since the FingeprintManager + FaceManager may not
+ // we check this here instead of onInit since the FingerprintManager + FaceManager may not
// have started up yet onInit
- final boolean hasFaceAuth = mAuthController.getFaceAuthSensorLocation() != null;
- final boolean hasUdfps = mAuthController.getUdfpsSensorLocation() != null;
- mHasUdfpsOrFaceAuthFeatures = hasFaceAuth || hasUdfps;
- if (!mHasUdfpsOrFaceAuthFeatures) {
- // Posting since removing a view in the middle of onAttach can lead to a crash in the
- // iteration loop when the view isn't last
- mView.setVisibility(View.GONE);
- mView.post(() -> {
- mView.setVisibility(View.VISIBLE);
- ((ViewGroup) mView.getParent()).removeView(mView);
- });
- return;
- }
-
- if (hasUdfps) {
- FingerprintSensorPropertiesInternal props = mAuthController.getUdfpsProps().get(0);
- mView.setLocation(new PointF(props.sensorLocationX, props.sensorLocationY),
- props.sensorRadius);
- } else {
- int[] props = mView.getContext().getResources().getIntArray(
- com.android.systemui.R.array.config_lock_icon_props);
- if (props == null || props.length < 3) {
- Log.e("LockIconViewController", "lock icon position should be "
- + "setup in config under config_lock_icon_props");
- props = new int[]{0, 0, 0};
- }
- mView.setLocation(new PointF(props[0], props[1]), props[2]);
- }
+ mHasUdfps = mAuthController.getUdfpsSensorLocation() != null;
+ updateConfiguration();
updateKeyguardShowing();
mUserUnlockedWithBiometric = false;
mIsBouncerShowing = mKeyguardViewController.isBouncerShowing();
@@ -194,9 +171,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
mStatusBarStateController.addCallback(mStatusBarStateListener);
mKeyguardStateController.addCallback(mKeyguardStateCallback);
- mAccessibilityManager.addTouchExplorationStateChangeListener(
- mTouchExplorationStateChangeListener);
-
+ mDownDetected = false;
updateVisibility();
}
@@ -206,8 +181,6 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback);
mStatusBarStateController.removeCallback(mStatusBarStateListener);
mKeyguardStateController.removeCallback(mKeyguardStateCallback);
- mAccessibilityManager.removeTouchExplorationStateChangeListener(
- mTouchExplorationStateChangeListener);
if (mCancelDelayedUpdateVisibilityRunnable != null) {
mCancelDelayedUpdateVisibilityRunnable.run();
@@ -219,18 +192,6 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
return mView.getLocationTop();
}
- private boolean onAffordanceClick() {
- if (mFalsingManager.isFalseTouch(DISABLED_UDFPS_AFFORDANCE)) {
- return false;
- }
-
- // pre-emptively set to true to hide view
- mIsBouncerShowing = true;
- updateVisibility();
- mKeyguardViewController.showBouncer(/* scrim */ true);
- return true;
- }
-
/**
* Set whether qs is expanded. When QS is expanded, don't show a DisabledUdfps affordance.
*/
@@ -245,32 +206,24 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
mCancelDelayedUpdateVisibilityRunnable = null;
}
- if (!mIsKeyguardShowing || (!mUdfpsEnrolled && !mFaceAuthEnrolled)) {
+ if (!mIsKeyguardShowing) {
mView.setVisibility(View.INVISIBLE);
return;
}
- // these three states are mutually exclusive:
- mShowButton = mUdfpsEnrolled && !mCanDismissLockScreen && !mRunningFPS
- && !mUserUnlockedWithBiometric && isLockScreen();
- mShowUnlockIcon = mFaceAuthEnrolled & mCanDismissLockScreen && isLockScreen();
- mShowLockIcon = !mUdfpsEnrolled && !mCanDismissLockScreen && isLockScreen()
- && mFaceAuthEnrolled;
+ mShowLockIcon = !mCanDismissLockScreen && !mUserUnlockedWithBiometric && isLockScreen()
+ && (!mUdfpsEnrolled || !mRunningFPS);
+ mShowUnlockIcon = mCanDismissLockScreen && isLockScreen();
- updateClickListener();
final CharSequence prevContentDescription = mView.getContentDescription();
- if (mShowButton) {
- mView.setImageDrawable(mButton);
+ if (mShowLockIcon) {
+ mView.setImageDrawable(mLockIcon);
mView.setVisibility(View.VISIBLE);
- mView.setContentDescription(mDisabledLabel);
+ mView.setContentDescription(mLockedLabel);
} else if (mShowUnlockIcon) {
mView.setImageDrawable(mUnlockIcon);
mView.setVisibility(View.VISIBLE);
mView.setContentDescription(mUnlockedLabel);
- } else if (mShowLockIcon) {
- mView.setImageDrawable(mLockIcon);
- mView.setVisibility(View.VISIBLE);
- mView.setContentDescription(mLockedLabel);
} else {
mView.setVisibility(View.INVISIBLE);
mView.setContentDescription(null);
@@ -293,10 +246,12 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
getResources().getString(R.string.accessibility_enter_hint));
public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(v, info);
- if (mShowButton || mShowLockIcon) {
- info.addAction(mAccessibilityAuthenticateHint);
- } else if (mShowUnlockIcon) {
- info.addAction(mAccessibilityEnterHint);
+ if (isClickable()) {
+ if (mShowLockIcon) {
+ info.addAction(mAccessibilityAuthenticateHint);
+ } else if (mShowUnlockIcon) {
+ info.addAction(mAccessibilityEnterHint);
+ }
}
}
};
@@ -308,18 +263,6 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
&& mStatusBarState == StatusBarState.KEYGUARD;
}
- private void updateClickListener() {
- if (mView != null) {
- mView.setOnClickListener(v -> onAffordanceClick());
- if (mAccessibilityManager.isTouchExplorationEnabled()) {
- mView.setOnLongClickListener(null);
- mView.setLongClickable(false);
- } else {
- mView.setOnLongClickListener(v -> onAffordanceClick());
- }
- }
- }
-
private void updateKeyguardShowing() {
mIsKeyguardShowing = mKeyguardStateController.isShowing()
&& !mKeyguardStateController.isKeyguardGoingAway();
@@ -332,13 +275,39 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
mLockIcon.setTint(color);
}
+ private void updateConfiguration() {
+ final DisplayMetrics metrics = mView.getContext().getResources().getDisplayMetrics();
+ mWidthPixels = metrics.widthPixels;
+ mHeightPixels = metrics.heightPixels;
+ mDensity = metrics.density;
+ mKgBottomAreaHeight = mView.getContext().getResources().getDimensionPixelSize(
+ R.dimen.keyguard_indication_margin_bottom)
+ + mView.getContext().getResources().getDimensionPixelSize(
+ R.dimen.keyguard_indication_bottom_padding);
+ updateLockIconLocation();
+ }
+
+ private void updateLockIconLocation() {
+ if (mHasUdfps) {
+ FingerprintSensorPropertiesInternal props = mAuthController.getUdfpsProps().get(0);
+ mView.setCenterLocation(new PointF(props.sensorLocationX, props.sensorLocationY),
+ props.sensorRadius);
+ } else {
+ final float distAboveKgBottomArea = 12 * mDensity;
+ final float radius = 36 * mDensity;
+ mView.setCenterLocation(
+ new PointF(mWidthPixels / 2,
+ mHeightPixels - mKgBottomAreaHeight - distAboveKgBottomArea
+ - radius / 2), (int) radius);
+ }
+
+ mView.getHitRect(mSensorTouchLocation);
+ }
+
@Override
public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
- pw.println("mHasUdfpsOrFaceAuthFeatures: " + mHasUdfpsOrFaceAuthFeatures);
pw.println("mUdfpsEnrolled: " + mUdfpsEnrolled);
- pw.println("mFaceAuthEnrolled: " + mFaceAuthEnrolled);
pw.println("mIsKeyguardShowing: " + mIsKeyguardShowing);
- pw.println(" mShowBouncerButton: " + mShowButton);
pw.println(" mShowUnlockIcon: " + mShowUnlockIcon);
pw.println(" mShowLockIcon: " + mShowLockIcon);
pw.println(" mIsDozing: " + mIsDozing);
@@ -348,6 +317,10 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
pw.println(" mCanDismissLockScreen: " + mCanDismissLockScreen);
pw.println(" mStatusBarState: " + StatusBarState.toShortString(mStatusBarState));
pw.println(" mQsExpanded: " + mQsExpanded);
+
+ if (mView != null) {
+ mView.dump(fd, pw, args);
+ }
}
private StatusBarStateController.StateListener mStatusBarStateListener =
@@ -420,7 +393,6 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
public void onKeyguardShowingChanged() {
updateKeyguardShowing();
mUdfpsEnrolled = mKeyguardUpdateMonitor.isUdfpsEnrolled();
- mFaceAuthEnrolled = mKeyguardUpdateMonitor.isFaceEnrolled();
updateVisibility();
}
@@ -447,10 +419,87 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
public void onOverlayChanged() {
updateColors();
}
+
+ @Override
+ public void onConfigChanged(Configuration newConfig) {
+ updateConfiguration();
+ }
};
- private final AccessibilityManager.TouchExplorationStateChangeListener
- mTouchExplorationStateChangeListener = enabled -> updateClickListener();
+ private final GestureDetector mGestureDetector =
+ new GestureDetector(new SimpleOnGestureListener() {
+ public boolean onDown(MotionEvent e) {
+ if (!isClickable()) {
+ mDownDetected = false;
+ return false;
+ }
+
+ // intercept all following touches until we see MotionEvent.ACTION_CANCEL UP or
+ // MotionEvent.ACTION_UP (see #onTouchEvent)
+ mDownDetected = true;
+ return true;
+ }
+
+ public void onLongPress(MotionEvent e) {
+ if (!wasClickableOnDownEvent()) {
+ return;
+ }
+
+ onAffordanceClick();
+ }
+
+ public boolean onSingleTapUp(MotionEvent e) {
+ if (!wasClickableOnDownEvent()) {
+ return false;
+ }
+
+ onAffordanceClick();
+ return true;
+ }
+
+ private boolean wasClickableOnDownEvent() {
+ return mDownDetected;
+ }
+
+ private void onAffordanceClick() {
+ if (mFalsingManager.isFalseTouch(LOCK_ICON)) {
+ return;
+ }
+
+ // pre-emptively set to true to hide view
+ mIsBouncerShowing = true;
+ updateVisibility();
+ mKeyguardViewController.showBouncer(/* scrim */ true);
+ }
+ });
+
+ /**
+ * Send touch events to this view and handles it if the touch is within this view and we are
+ * in a 'clickable' state
+ * @return whether to intercept the touch event
+ */
+ public boolean onTouchEvent(MotionEvent event) {
+ if (mSensorTouchLocation.contains((int) event.getX(), (int) event.getY())
+ && mView.getVisibility() == View.VISIBLE) {
+ mGestureDetector.onTouchEvent(event);
+ }
+
+ // 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
+ // after the lock icon disappears on device entry
+ if (mDownDetected) {
+ if (event.getAction() == MotionEvent.ACTION_CANCEL
+ || event.getAction() == MotionEvent.ACTION_UP) {
+ mDownDetected = false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isClickable() {
+ return mUdfpsEnrolled || mShowUnlockIcon;
+ }
/**
* Set the alpha of this view.