Merge "Adding accessibility support to the tablet swipe unlock." into ics-mr1

This commit is contained in:
Svetoslav Ganov
2011-10-26 11:30:06 -07:00
committed by Android (Google) Code Review
2 changed files with 82 additions and 11 deletions

View File

@@ -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.
*/

View File

@@ -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] -->