Loading core/java/com/android/internal/widget/WaveView.java +79 −11 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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(); Loading @@ -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; Loading @@ -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. */ Loading core/res/res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -3225,6 +3225,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] --> Loading Loading
core/java/com/android/internal/widget/WaveView.java +79 −11 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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(); Loading @@ -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; Loading @@ -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. */ Loading
core/res/res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -3225,6 +3225,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] --> Loading