Skip to content

Commit 1a3ad7d

Browse files
sganovAndroid (Google) Code Review
authored andcommitted
Merge "Adding accessibility support to the tablet swipe unlock." into ics-mr1
2 parents 6e03b22 + 6033c08 commit 1a3ad7d

2 files changed

Lines changed: 82 additions & 11 deletions

File tree

core/java/com/android/internal/widget/WaveView.java

Lines changed: 79 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,13 @@
2626
import android.graphics.Canvas;
2727
import android.graphics.drawable.BitmapDrawable;
2828
import android.os.Vibrator;
29+
import android.text.TextUtils;
2930
import android.util.AttributeSet;
3031
import android.util.Log;
3132
import android.view.MotionEvent;
3233
import android.view.View;
34+
import android.view.accessibility.AccessibilityEvent;
35+
import android.view.accessibility.AccessibilityManager;
3336

3437
import com.android.internal.R;
3538

@@ -64,6 +67,18 @@ public class WaveView extends View implements ValueAnimator.AnimatorUpdateListen
6467
private static final long DELAY_INCREMENT2 = 12; // increment per wave while not tracking
6568
private static final long WAVE_DELAY = WAVE_DURATION / WAVE_COUNT; // initial propagation delay
6669

70+
/**
71+
* The scale by which to multiply the unlock handle width to compute the radius
72+
* in which it can be grabbed when accessibility is disabled.
73+
*/
74+
private static final float GRAB_HANDLE_RADIUS_SCALE_ACCESSIBILITY_DISABLED = 0.5f;
75+
76+
/**
77+
* The scale by which to multiply the unlock handle width to compute the radius
78+
* in which it can be grabbed when accessibility is enabled (more generous).
79+
*/
80+
private static final float GRAB_HANDLE_RADIUS_SCALE_ACCESSIBILITY_ENABLED = 1.0f;
81+
6782
private Vibrator mVibrator;
6883
private OnTriggerListener mOnTriggerListener;
6984
private ArrayList<DrawableHolder> mDrawables = new ArrayList<DrawableHolder>(3);
@@ -450,6 +465,27 @@ public void run() {
450465
}
451466
};
452467

468+
@Override
469+
public boolean onHoverEvent(MotionEvent event) {
470+
if (AccessibilityManager.getInstance(mContext).isTouchExplorationEnabled()) {
471+
final int action = event.getAction();
472+
switch (action) {
473+
case MotionEvent.ACTION_HOVER_ENTER:
474+
event.setAction(MotionEvent.ACTION_DOWN);
475+
break;
476+
case MotionEvent.ACTION_HOVER_MOVE:
477+
event.setAction(MotionEvent.ACTION_MOVE);
478+
break;
479+
case MotionEvent.ACTION_HOVER_EXIT:
480+
event.setAction(MotionEvent.ACTION_UP);
481+
break;
482+
}
483+
onTouchEvent(event);
484+
event.setAction(action);
485+
}
486+
return super.onHoverEvent(event);
487+
}
488+
453489
@Override
454490
public boolean onTouchEvent(MotionEvent event) {
455491
final int action = event.getAction();
@@ -460,21 +496,12 @@ public boolean onTouchEvent(MotionEvent event) {
460496
case MotionEvent.ACTION_DOWN:
461497
removeCallbacks(mLockTimerActions);
462498
mFingerDown = true;
463-
setGrabbedState(OnTriggerListener.CENTER_HANDLE);
464-
{
465-
float x = mMouseX - mUnlockHalo.getX();
466-
float y = mMouseY - mUnlockHalo.getY();
467-
float dist = (float) Math.hypot(x, y);
468-
if (dist < mUnlockHalo.getWidth()*0.5f) {
469-
if (mLockState == STATE_READY) {
470-
mLockState = STATE_START_ATTEMPT;
471-
}
472-
}
473-
}
499+
tryTransitionToStartAttemptState(event);
474500
handled = true;
475501
break;
476502

477503
case MotionEvent.ACTION_MOVE:
504+
tryTransitionToStartAttemptState(event);
478505
handled = true;
479506
break;
480507

@@ -501,6 +528,47 @@ public boolean onTouchEvent(MotionEvent event) {
501528
return handled ? true : super.onTouchEvent(event);
502529
}
503530

531+
/**
532+
* Tries to transition to start attempt state.
533+
*
534+
* @param event A motion event.
535+
*/
536+
private void tryTransitionToStartAttemptState(MotionEvent event) {
537+
final float dx = event.getX() - mUnlockHalo.getX();
538+
final float dy = event.getY() - mUnlockHalo.getY();
539+
float dist = (float) Math.hypot(dx, dy);
540+
if (dist <= getScaledGrabHandleRadius()) {
541+
setGrabbedState(OnTriggerListener.CENTER_HANDLE);
542+
if (mLockState == STATE_READY) {
543+
mLockState = STATE_START_ATTEMPT;
544+
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
545+
announceUnlockHandle();
546+
}
547+
}
548+
}
549+
}
550+
551+
/**
552+
* @return The radius in which the handle is grabbed scaled based on
553+
* whether accessibility is enabled.
554+
*/
555+
private float getScaledGrabHandleRadius() {
556+
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
557+
return GRAB_HANDLE_RADIUS_SCALE_ACCESSIBILITY_ENABLED * mUnlockHalo.getWidth();
558+
} else {
559+
return GRAB_HANDLE_RADIUS_SCALE_ACCESSIBILITY_DISABLED * mUnlockHalo.getWidth();
560+
}
561+
}
562+
563+
/**
564+
* Announces the unlock handle if accessibility is enabled.
565+
*/
566+
private void announceUnlockHandle() {
567+
setContentDescription(mContext.getString(R.string.description_target_unlock_tablet));
568+
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
569+
setContentDescription(null);
570+
}
571+
504572
/**
505573
* Triggers haptic feedback.
506574
*/

core/res/res/values/strings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3248,6 +3248,9 @@
32483248
<!-- Description of the sound on target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
32493249
<string name="description_target_soundon">Sound on</string>
32503250

3251+
<!-- Description of the unlock handle in the Slide unlock screen for tablets. [CHAR LIMIT=NONE] -->
3252+
<string name="description_target_unlock_tablet">Swipe to unlock.</string>
3253+
32513254
<!-- Announce that a headset is required to hear keyboard keys while typing a password. [CHAR LIMIT=NONE] -->
32523255
<string name="keyboard_headset_required_to_hear_password">Plug in a headset to hear password keys spoken aloud.</string>
32533256
<!-- The value of a keyboard key announced when accessibility is enabled and no headsed is used. [CHAR LIMIT=NONE] -->

0 commit comments

Comments
 (0)