Merge "Adding accessibility support to the tablet swipe unlock." into ics-mr1
This commit is contained in:
committed by
Android (Google) Code Review
commit
1a3ad7d18f
@@ -26,10 +26,13 @@ import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.os.Vibrator;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
@@ -64,6 +67,18 @@ public class WaveView extends View implements ValueAnimator.AnimatorUpdateListen
|
||||
private static final long DELAY_INCREMENT2 = 12; // increment per wave while not tracking
|
||||
private static final long WAVE_DELAY = WAVE_DURATION / WAVE_COUNT; // initial propagation delay
|
||||
|
||||
/**
|
||||
* The scale by which to multiply the unlock handle width to compute the radius
|
||||
* in which it can be grabbed when accessibility is disabled.
|
||||
*/
|
||||
private static final float GRAB_HANDLE_RADIUS_SCALE_ACCESSIBILITY_DISABLED = 0.5f;
|
||||
|
||||
/**
|
||||
* The scale by which to multiply the unlock handle width to compute the radius
|
||||
* in which it can be grabbed when accessibility is enabled (more generous).
|
||||
*/
|
||||
private static final float GRAB_HANDLE_RADIUS_SCALE_ACCESSIBILITY_ENABLED = 1.0f;
|
||||
|
||||
private Vibrator mVibrator;
|
||||
private OnTriggerListener mOnTriggerListener;
|
||||
private ArrayList<DrawableHolder> mDrawables = new ArrayList<DrawableHolder>(3);
|
||||
@@ -450,6 +465,27 @@ public class WaveView extends View implements ValueAnimator.AnimatorUpdateListen
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean onHoverEvent(MotionEvent event) {
|
||||
if (AccessibilityManager.getInstance(mContext).isTouchExplorationEnabled()) {
|
||||
final int action = event.getAction();
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_HOVER_ENTER:
|
||||
event.setAction(MotionEvent.ACTION_DOWN);
|
||||
break;
|
||||
case MotionEvent.ACTION_HOVER_MOVE:
|
||||
event.setAction(MotionEvent.ACTION_MOVE);
|
||||
break;
|
||||
case MotionEvent.ACTION_HOVER_EXIT:
|
||||
event.setAction(MotionEvent.ACTION_UP);
|
||||
break;
|
||||
}
|
||||
onTouchEvent(event);
|
||||
event.setAction(action);
|
||||
}
|
||||
return super.onHoverEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
final int action = event.getAction();
|
||||
@@ -460,21 +496,12 @@ public class WaveView extends View implements ValueAnimator.AnimatorUpdateListen
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
removeCallbacks(mLockTimerActions);
|
||||
mFingerDown = true;
|
||||
setGrabbedState(OnTriggerListener.CENTER_HANDLE);
|
||||
{
|
||||
float x = mMouseX - mUnlockHalo.getX();
|
||||
float y = mMouseY - mUnlockHalo.getY();
|
||||
float dist = (float) Math.hypot(x, y);
|
||||
if (dist < mUnlockHalo.getWidth()*0.5f) {
|
||||
if (mLockState == STATE_READY) {
|
||||
mLockState = STATE_START_ATTEMPT;
|
||||
}
|
||||
}
|
||||
}
|
||||
tryTransitionToStartAttemptState(event);
|
||||
handled = true;
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
tryTransitionToStartAttemptState(event);
|
||||
handled = true;
|
||||
break;
|
||||
|
||||
@@ -501,6 +528,47 @@ public class WaveView extends View implements ValueAnimator.AnimatorUpdateListen
|
||||
return handled ? true : super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to transition to start attempt state.
|
||||
*
|
||||
* @param event A motion event.
|
||||
*/
|
||||
private void tryTransitionToStartAttemptState(MotionEvent event) {
|
||||
final float dx = event.getX() - mUnlockHalo.getX();
|
||||
final float dy = event.getY() - mUnlockHalo.getY();
|
||||
float dist = (float) Math.hypot(dx, dy);
|
||||
if (dist <= getScaledGrabHandleRadius()) {
|
||||
setGrabbedState(OnTriggerListener.CENTER_HANDLE);
|
||||
if (mLockState == STATE_READY) {
|
||||
mLockState = STATE_START_ATTEMPT;
|
||||
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
|
||||
announceUnlockHandle();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The radius in which the handle is grabbed scaled based on
|
||||
* whether accessibility is enabled.
|
||||
*/
|
||||
private float getScaledGrabHandleRadius() {
|
||||
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
|
||||
return GRAB_HANDLE_RADIUS_SCALE_ACCESSIBILITY_ENABLED * mUnlockHalo.getWidth();
|
||||
} else {
|
||||
return GRAB_HANDLE_RADIUS_SCALE_ACCESSIBILITY_DISABLED * mUnlockHalo.getWidth();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Announces the unlock handle if accessibility is enabled.
|
||||
*/
|
||||
private void announceUnlockHandle() {
|
||||
setContentDescription(mContext.getString(R.string.description_target_unlock_tablet));
|
||||
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
|
||||
setContentDescription(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers haptic feedback.
|
||||
*/
|
||||
|
||||
@@ -3248,6 +3248,9 @@
|
||||
<!-- Description of the sound on target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
|
||||
<string name="description_target_soundon">Sound on</string>
|
||||
|
||||
<!-- Description of the unlock handle in the Slide unlock screen for tablets. [CHAR LIMIT=NONE] -->
|
||||
<string name="description_target_unlock_tablet">Swipe to unlock.</string>
|
||||
|
||||
<!-- Announce that a headset is required to hear keyboard keys while typing a password. [CHAR LIMIT=NONE] -->
|
||||
<string name="keyboard_headset_required_to_hear_password">Plug in a headset to hear password keys spoken aloud.</string>
|
||||
<!-- The value of a keyboard key announced when accessibility is enabled and no headsed is used. [CHAR LIMIT=NONE] -->
|
||||
|
||||
Reference in New Issue
Block a user