diff options
author | Yorke Lee <yorkelee@google.com> | 2015-06-24 17:07:47 -0700 |
---|---|---|
committer | Yorke Lee <yorkelee@google.com> | 2015-06-25 14:42:38 -0700 |
commit | 1e0585f3f789e4ea28f31352eced59c73cf8b373 (patch) | |
tree | dc79b050e804b3b4cc65e2746a500158be03c71b /InCallUI/src/com/android/incallui/widget | |
parent | 4019d6377f7da43cd58f2435f03bd240c80aa520 (diff) |
Make switch access work for incoming call screen
An accessibility click on the glowpad now exposes the touch targets
as virtual views to accessibility services. Performing an accessibility
click on each virtual view performs the same function as swiping towards
that target.
Mark contact photo as unimportant for accessibility, it doesn't provide
any useful context or functionality.
Bug: 19075527
Change-Id: I2e980394175bf77379f5cb99126dd5970e0f0555
Diffstat (limited to 'InCallUI/src/com/android/incallui/widget')
-rw-r--r-- | InCallUI/src/com/android/incallui/widget/multiwaveview/GlowPadView.java | 115 | ||||
-rw-r--r-- | InCallUI/src/com/android/incallui/widget/multiwaveview/TargetDrawable.java | 13 |
2 files changed, 128 insertions, 0 deletions
diff --git a/InCallUI/src/com/android/incallui/widget/multiwaveview/GlowPadView.java b/InCallUI/src/com/android/incallui/widget/multiwaveview/GlowPadView.java index 4bd27db9c..23200279e 100644 --- a/InCallUI/src/com/android/incallui/widget/multiwaveview/GlowPadView.java +++ b/InCallUI/src/com/android/incallui/widget/multiwaveview/GlowPadView.java @@ -29,9 +29,14 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Canvas; +import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Vibrator; +import android.support.v4.view.ViewCompat; +import android.support.v4.view.accessibility.AccessibilityEventCompat; +import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; +import android.support.v4.widget.ExploreByTouchHelper; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; @@ -39,11 +44,16 @@ import android.util.TypedValue; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; +import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; +import android.view.accessibility.AccessibilityNodeInfo; +import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; +import android.view.accessibility.AccessibilityNodeProvider; import com.android.incallui.R; import java.util.ArrayList; +import java.util.List; /** * This is a copy of com.android.internal.widget.multiwaveview.GlowPadView with minor changes @@ -124,6 +134,9 @@ public class GlowPadView extends View { private boolean mDragging; private int mNewTargetResources; + private AccessibilityNodeProvider mAccessibilityNodeProvider; + private GlowpadExploreByTouchHelper mExploreByTouchHelper; + private class AnimationBundle extends ArrayList<Tweener> { private static final long serialVersionUID = 0xA84D78726F127468L; private boolean mSuspended; @@ -274,6 +287,9 @@ public class GlowPadView extends View { mPointCloud = new PointCloud(pointDrawable); mPointCloud.makePointCloud(mInnerRadius, mOuterRadius); mPointCloud.glowManager.setRadius(mGlowRadius); + + mExploreByTouchHelper = new GlowpadExploreByTouchHelper(this); + ViewCompat.setAccessibilityDelegate(this, mExploreByTouchHelper); } private int getResourceId(TypedArray a, int id) { @@ -1355,4 +1371,103 @@ public class GlowPadView extends View { } return replaced; } + + public class GlowpadExploreByTouchHelper extends ExploreByTouchHelper { + + private Rect mBounds = new Rect(); + + public GlowpadExploreByTouchHelper(View forView) { + super(forView); + } + + @Override + protected int getVirtualViewAt(float x, float y) { + if (mGrabbedState == OnTriggerListener.CENTER_HANDLE) { + for (int i = 0; i < mTargetDrawables.size(); i++) { + final TargetDrawable target = mTargetDrawables.get(i); + if (target.isEnabled() && target.getBounds().contains((int) x, (int) y)) { + return i; + } + } + return INVALID_ID; + } else { + return HOST_ID; + } + } + + @Override + protected void getVisibleVirtualViews(List<Integer> virtualViewIds) { + if (mGrabbedState == OnTriggerListener.CENTER_HANDLE) { + // Add virtual views backwards so that accessibility services like switch + // access traverse them in the correct order + for (int i = mTargetDrawables.size() - 1; i >= 0; i--) { + if (mTargetDrawables.get(i).isEnabled()) { + virtualViewIds.add(i); + } + } + } + } + + @Override + protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) { + if (virtualViewId >= 0 && virtualViewId < mTargetDescriptions.size()) { + event.setContentDescription(mTargetDescriptions.get(virtualViewId)); + } + } + + @Override + public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { + if (host == GlowPadView.this && event.getEventType() + == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) { + event.setContentChangeTypes(AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE); + } + super.onInitializeAccessibilityEvent(host, event); + } + + @Override + public void onPopulateNodeForHost(AccessibilityNodeInfoCompat node) { + if (mGrabbedState == OnTriggerListener.NO_HANDLE) { + node.setClickable(true); + node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK); + } + mBounds.set(0, 0, GlowPadView.this.getWidth(), GlowPadView.this.getHeight()); + node.setBoundsInParent(mBounds); + } + + @Override + public boolean performAccessibilityAction(View host, int action, Bundle args) { + if (mGrabbedState == OnTriggerListener.NO_HANDLE) { + // Simulate handle being grabbed to expose targets. + trySwitchToFirstTouchState(mWaveCenterX, mWaveCenterY); + invalidateRoot(); + return true; + } + return super.performAccessibilityAction(host, action, args); + } + + @Override + protected void onPopulateNodeForVirtualView(int virtualViewId, + AccessibilityNodeInfoCompat node) { + if (virtualViewId < mTargetDrawables.size()) { + final TargetDrawable target = mTargetDrawables.get(virtualViewId); + node.setBoundsInParent(target.getBounds()); + node.setClickable(true); + node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK); + node.setContentDescription(getTargetDescription(virtualViewId)); + } + } + + @Override + protected boolean onPerformActionForVirtualView(int virtualViewId, int action, + Bundle arguments) { + if (action == AccessibilityNodeInfo.ACTION_CLICK) { + if (virtualViewId >= 0 && virtualViewId < mTargetDrawables.size()) { + dispatchTriggerEvent(virtualViewId); + return true; + } + } + return false; + } + + } } diff --git a/InCallUI/src/com/android/incallui/widget/multiwaveview/TargetDrawable.java b/InCallUI/src/com/android/incallui/widget/multiwaveview/TargetDrawable.java index d83a28c11..adc5324eb 100644 --- a/InCallUI/src/com/android/incallui/widget/multiwaveview/TargetDrawable.java +++ b/InCallUI/src/com/android/incallui/widget/multiwaveview/TargetDrawable.java @@ -19,6 +19,7 @@ package com.android.incallui.widget.multiwaveview; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.ColorFilter; +import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.StateListDrawable; import android.util.Log; @@ -46,6 +47,7 @@ public class TargetDrawable { private boolean mEnabled = true; private final int mResourceId; private int mNumDrawables = 1; + private Rect mBounds; /** * This is changed from the framework version to pass in the number of drawables in the @@ -214,6 +216,17 @@ public class TargetDrawable { return mDrawable != null ? mDrawable.getIntrinsicHeight() : 0; } + public Rect getBounds() { + if (mBounds == null) { + mBounds = new Rect(); + } + mBounds.set((int) (mTranslationX + mPositionX - getWidth() * 0.5), + (int) (mTranslationY + mPositionY - getHeight() * 0.5), + (int) (mTranslationX + mPositionX + getWidth() * 0.5), + (int) (mTranslationY + mPositionY + getHeight() * 0.5)); + return mBounds; + } + public void draw(Canvas canvas) { if (mDrawable == null || !mEnabled) { return; |