diff options
Diffstat (limited to 'packages/SystemUI/src')
-rw-r--r-- | packages/SystemUI/src/com/android/keyguard/LockIconViewController.java | 71 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java | 41 |
2 files changed, 102 insertions, 10 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java index 66ea2ad001fd..9b0ae6b6b4c5 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java @@ -29,9 +29,12 @@ import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.util.Log; import android.view.View; import android.view.ViewGroup; +import android.view.accessibility.AccessibilityManager; +import android.view.accessibility.AccessibilityNodeInfo; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import com.android.settingslib.Utils; import com.android.systemui.Dumpable; @@ -63,6 +66,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme @NonNull private final KeyguardStateController mKeyguardStateController; @NonNull private final FalsingManager mFalsingManager; @NonNull private final AuthController mAuthController; + @NonNull private final AccessibilityManager mAccessibilityManager; private boolean mHasUdfpsOrFaceAuthFeatures; private boolean mUdfpsEnrolled; @@ -93,19 +97,17 @@ public class LockIconViewController extends ViewController<LockIconView> impleme @NonNull KeyguardStateController keyguardStateController, @NonNull FalsingManager falsingManager, @NonNull AuthController authController, - @NonNull DumpManager dumpManager + @NonNull DumpManager dumpManager, + @NonNull AccessibilityManager accessibilityManager ) { super(view); - if (mView != null) { - mView.setOnClickListener(v -> onAffordanceClick()); - mView.setOnLongClickListener(v -> onAffordanceClick()); - } mStatusBarStateController = statusBarStateController; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mAuthController = authController; mKeyguardViewController = keyguardViewController; mKeyguardStateController = keyguardStateController; mFalsingManager = falsingManager; + mAccessibilityManager = accessibilityManager; final Context context = view.getContext(); mButton = context.getResources().getDrawable( @@ -122,6 +124,11 @@ public class LockIconViewController extends ViewController<LockIconView> impleme } @Override + protected void onInit() { + mView.setAccessibilityDelegate(mAccessibilityDelegate); + } + + @Override protected void onViewAttached() { // we check this here instead of onInit since the FingeprintManager + FaceManager may not // have started up yet onInit @@ -163,6 +170,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback); mStatusBarStateController.addCallback(mStatusBarStateListener); mKeyguardStateController.addCallback(mKeyguardStateCallback); + mAccessibilityManager.addTouchExplorationStateChangeListener( + mTouchExplorationStateChangeListener); updateVisibility(); } @@ -172,6 +181,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback); mStatusBarStateController.removeCallback(mStatusBarStateListener); mKeyguardStateController.removeCallback(mKeyguardStateCallback); + mAccessibilityManager.removeTouchExplorationStateChangeListener( + mTouchExplorationStateChangeListener); } public float getTop() { @@ -210,20 +221,56 @@ public class LockIconViewController extends ViewController<LockIconView> impleme mShowLockIcon = !mUdfpsEnrolled && !mCanDismissLockScreen && isLockScreen() && mFaceAuthEnrolled; + updateClickListener(); if (mShowButton) { mView.setImageDrawable(mButton); mView.setVisibility(View.VISIBLE); + mView.setContentDescription(getResources().getString( + R.string.accessibility_udfps_disabled_button)); } else if (mShowUnlockIcon) { mView.setImageDrawable(mUnlockIcon); mView.setVisibility(View.VISIBLE); + mView.setContentDescription(getResources().getString( + R.string.accessibility_unlock_button)); } else if (mShowLockIcon) { mView.setImageDrawable(mLockIcon); mView.setVisibility(View.VISIBLE); + mView.setContentDescription(getResources().getString( + R.string.accessibility_lock_icon)); } else { mView.setVisibility(View.INVISIBLE); + mView.setContentDescription(null); } } + private final View.AccessibilityDelegate mAccessibilityDelegate = + new View.AccessibilityDelegate() { + private final AccessibilityNodeInfo.AccessibilityAction mAccessibilityAuthenticateHint = + new AccessibilityNodeInfo.AccessibilityAction( + AccessibilityNodeInfoCompat.ACTION_CLICK, + getResources().getString(R.string.accessibility_authenticate_hint)); + private final AccessibilityNodeInfo.AccessibilityAction mAccessibilityEnterHint = + new AccessibilityNodeInfo.AccessibilityAction( + AccessibilityNodeInfoCompat.ACTION_CLICK, + getResources().getString(R.string.accessibility_enter_hint)); + public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(v, info); + removeAllActions(info); + if (mShowButton || mShowLockIcon) { + info.addAction(mAccessibilityAuthenticateHint); + } else if (mShowUnlockIcon) { + info.addAction(mAccessibilityEnterHint); + } + } + + private void removeAllActions(AccessibilityNodeInfo info) { + info.removeAction(mAccessibilityAuthenticateHint); + info.removeAction(mAccessibilityEnterHint); + info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK); + mView.setLongClickable(false); + } + }; + private boolean isLockScreen() { return !mIsDozing && !mIsBouncerShowing @@ -231,6 +278,17 @@ 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); + } else { + mView.setOnLongClickListener(v -> onAffordanceClick()); + } + } + } + @Override public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) { pw.println(" mShowBouncerButton: " + mShowButton); @@ -298,4 +356,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme updateVisibility(); } }; + + private final AccessibilityManager.TouchExplorationStateChangeListener + mTouchExplorationStateChangeListener = enabled -> updateClickListener(); } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 7ebfb7266c11..ee5fb313fff3 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -28,7 +28,6 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.res.Resources; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.RectF; @@ -55,6 +54,7 @@ import android.view.Surface; import android.view.VelocityTracker; import android.view.View; import android.view.WindowManager; +import android.view.accessibility.AccessibilityManager; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.KeyguardUpdateMonitor; @@ -108,6 +108,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback { @NonNull private final Handler mMainHandler; @NonNull private final FalsingManager mFalsingManager; @NonNull private final PowerManager mPowerManager; + @NonNull private final AccessibilityManager mAccessibilityManager; // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple // sensors, this, in addition to a lot of the code here, will be updated. @VisibleForTesting final FingerprintSensorPropertiesInternal mSensorProps; @@ -276,6 +277,13 @@ public class UdfpsController implements DozeReceiver, HbmCallback { private final UdfpsView.OnTouchListener mOnTouchListener = (view, event) -> onTouch(view, event, true); + @SuppressLint("ClickableViewAccessibility") + private final UdfpsView.OnHoverListener mOnHoverListener = (view, event) -> + onTouch(view, event, true); + + private final AccessibilityManager.TouchExplorationStateChangeListener + mTouchExplorationStateChangeListener = enabled -> updateTouchListener(); + /** * @param x coordinate * @param y coordinate @@ -300,6 +308,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback { udfpsView.onTouchOutsideView(); break; case MotionEvent.ACTION_DOWN: + case MotionEvent.ACTION_HOVER_ENTER: // To simplify the lifecycle of the velocity tracker, make sure it's never null // after ACTION_DOWN, and always null after ACTION_CANCEL or ACTION_UP. if (mVelocityTracker == null) { @@ -322,6 +331,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback { break; case MotionEvent.ACTION_MOVE: + case MotionEvent.ACTION_HOVER_MOVE: final int idx = mActivePointerId == -1 ? event.getPointerId(0) : event.findPointerIndex(mActivePointerId); @@ -388,6 +398,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback { case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_HOVER_EXIT: mActivePointerId = -1; if (mVelocityTracker != null) { mVelocityTracker.recycle(); @@ -409,10 +420,9 @@ public class UdfpsController implements DozeReceiver, HbmCallback { @Inject public UdfpsController(@NonNull Context context, - @Main Resources resources, @NonNull LayoutInflater inflater, @Nullable FingerprintManager fingerprintManager, - WindowManager windowManager, + @NonNull WindowManager windowManager, @NonNull StatusBarStateController statusBarStateController, @Main DelayableExecutor fgExecutor, @NonNull StatusBar statusBar, @@ -421,7 +431,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback { @NonNull KeyguardUpdateMonitor keyguardUpdateMonitor, @NonNull KeyguardViewMediator keyguardViewMediator, @NonNull FalsingManager falsingManager, - @NonNull PowerManager powerManager) { + @NonNull PowerManager powerManager, + @NonNull AccessibilityManager accessibilityManager) { mContext = context; // TODO (b/185124905): inject main handler and vibrator once done prototyping mMainHandler = new Handler(Looper.getMainLooper()); @@ -440,6 +451,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback { mKeyguardViewMediator = keyguardViewMediator; mFalsingManager = falsingManager; mPowerManager = powerManager; + mAccessibilityManager = accessibilityManager; mSensorProps = findFirstUdfps(); // At least one UDFPS sensor exists @@ -577,7 +589,9 @@ public class UdfpsController implements DozeReceiver, HbmCallback { mView.setAnimationViewController(animation); mWindowManager.addView(mView, computeLayoutParams(animation)); - mView.setOnTouchListener(mOnTouchListener); + mAccessibilityManager.addTouchExplorationStateChangeListener( + mTouchExplorationStateChangeListener); + updateTouchListener(); } catch (RuntimeException e) { Log.e(TAG, "showUdfpsOverlay | failed to add window", e); } @@ -650,7 +664,10 @@ public class UdfpsController implements DozeReceiver, HbmCallback { onFingerUp(); mWindowManager.removeView(mView); mView.setOnTouchListener(null); + mView.setOnHoverListener(null); mView.setAnimationViewController(null); + mAccessibilityManager.removeTouchExplorationStateChangeListener( + mTouchExplorationStateChangeListener); mView = null; } else { Log.v(TAG, "hideUdfpsOverlay | the overlay is already hidden"); @@ -758,4 +775,18 @@ public class UdfpsController implements DozeReceiver, HbmCallback { return defaultEffect; } } + + private void updateTouchListener() { + if (mView == null) { + return; + } + + if (mAccessibilityManager.isTouchExplorationEnabled()) { + mView.setOnHoverListener(mOnHoverListener); + mView.setOnTouchListener(null); + } else { + mView.setOnHoverListener(null); + mView.setOnTouchListener(mOnTouchListener); + } + } } |