summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2014-07-17 01:26:50 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-07-16 21:54:23 +0000
commit889fc94ffa70633e510e812b9da86723f4eee384 (patch)
treeab61f2bcf47dae1f616ec15ad729ba2520dfd133 /core
parent98b270309a342be0971320c5731f495a901ca4e4 (diff)
parentcce47eb580d666ead1f6095d1e3b65233592bbaa (diff)
downloadframeworks_base-889fc94ffa70633e510e812b9da86723f4eee384.zip
frameworks_base-889fc94ffa70633e510e812b9da86723f4eee384.tar.gz
frameworks_base-889fc94ffa70633e510e812b9da86723f4eee384.tar.bz2
Merge "Add accessibility text contrast setting" into lmp-dev
Diffstat (limited to 'core')
-rw-r--r--core/java/android/provider/Settings.java9
-rw-r--r--core/java/android/view/GLES20Canvas.java10
-rw-r--r--core/java/android/view/View.java6
-rw-r--r--core/java/android/view/ViewRootImpl.java32
-rw-r--r--core/java/android/view/accessibility/AccessibilityManager.java118
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp7
6 files changed, 168 insertions, 14 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 9f1279a..bc069ca 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3678,6 +3678,14 @@ public final class Settings {
public static final String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
/**
+ * Whether to draw text with high contrast while in accessibility mode.
+ *
+ * @hide
+ */
+ public static final String ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED =
+ "high_text_contrast_enabled";
+
+ /**
* If injection of accessibility enhancing JavaScript screen-reader
* is enabled.
* <p>
@@ -4644,6 +4652,7 @@ public final class Settings {
TOUCH_EXPLORATION_ENABLED,
ACCESSIBILITY_ENABLED,
ACCESSIBILITY_SPEAK_PASSWORD,
+ ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED,
ACCESSIBILITY_CAPTIONING_ENABLED,
ACCESSIBILITY_CAPTIONING_LOCALE,
ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR,
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index d7d3c72..910f862 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -168,7 +168,15 @@ class GLES20Canvas extends HardwareCanvas {
nSetViewport(mRenderer, width, height);
}
- private static native void nSetViewport(long renderer, int width, int height);
+ private static native void nSetViewport(long renderer,
+ int width, int height);
+
+ @Override
+ public void setHighContrastText(boolean highContrastText) {
+ nSetHighContrastText(mRenderer, highContrastText);
+ }
+
+ private static native void nSetHighContrastText(long renderer, boolean highContrastText);
@Override
public int onPreDraw(Rect dirty) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index fdbc619..a3e2c96 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -13746,6 +13746,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
int layerType = getLayerType();
final HardwareCanvas canvas = renderNode.start(width, height);
+ canvas.setHighContrastText(mAttachInfo.mHighContrastText);
try {
final HardwareLayer layer = getHardwareLayer();
@@ -19913,6 +19914,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
boolean mViewScrollChanged;
/**
+ * Set to true if high contrast mode enabled
+ */
+ boolean mHighContrastText;
+
+ /**
* Global to the view hierarchy used as a temporary for dealing with
* x/y points in the transparent region computations.
*/
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index f3ad988..a8d3f99 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -63,6 +63,7 @@ import android.view.View.MeasureSpec;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
+import android.view.accessibility.AccessibilityManager.HighTextContrastChangeListener;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeProvider;
import android.view.accessibility.IAccessibilityInteractionConnection;
@@ -313,6 +314,7 @@ public final class ViewRootImpl implements ViewParent,
AccessibilityInteractionController mAccessibilityInteractionController;
AccessibilityInteractionConnectionManager mAccessibilityInteractionConnectionManager;
+ HighContrastTextManager mHighContrastTextManager;
SendWindowContentChangedAccessibilityEvent mSendWindowContentChangedAccessibilityEvent;
@@ -370,12 +372,15 @@ public final class ViewRootImpl implements ViewParent,
mPreviousTransparentRegion = new Region();
mFirst = true; // true for the first time the view is added
mAdded = false;
+ mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this);
mAccessibilityManager = AccessibilityManager.getInstance(context);
mAccessibilityInteractionConnectionManager =
new AccessibilityInteractionConnectionManager();
mAccessibilityManager.addAccessibilityStateChangeListener(
mAccessibilityInteractionConnectionManager);
- mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this);
+ mHighContrastTextManager = new HighContrastTextManager();
+ mAccessibilityManager.addHighTextContrastStateChangeListener(
+ mHighContrastTextManager);
mViewConfiguration = ViewConfiguration.get(context);
mDensity = context.getResources().getDisplayMetrics().densityDpi;
mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi;
@@ -2914,6 +2919,8 @@ public final class ViewRootImpl implements ViewParent,
mAccessibilityInteractionConnectionManager.ensureNoConnection();
mAccessibilityManager.removeAccessibilityStateChangeListener(
mAccessibilityInteractionConnectionManager);
+ mAccessibilityManager.removeHighTextContrastStateChangeListener(
+ mHighContrastTextManager);
removeSendWindowContentChangedCallback();
destroyHardwareRenderer();
@@ -6585,7 +6592,7 @@ public final class ViewRootImpl implements ViewParent,
public void onAccessibilityStateChanged(boolean enabled) {
if (enabled) {
ensureConnection();
- if (mAttachInfo != null && mAttachInfo.mHasWindowFocus) {
+ if (mAttachInfo.mHasWindowFocus) {
mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
View focusedView = mView.findFocus();
if (focusedView != null && focusedView != mView) {
@@ -6599,14 +6606,12 @@ public final class ViewRootImpl implements ViewParent,
}
public void ensureConnection() {
- if (mAttachInfo != null) {
- final boolean registered =
+ final boolean registered =
mAttachInfo.mAccessibilityWindowId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
- if (!registered) {
- mAttachInfo.mAccessibilityWindowId =
+ if (!registered) {
+ mAttachInfo.mAccessibilityWindowId =
mAccessibilityManager.addAccessibilityInteractionConnection(mWindow,
new AccessibilityInteractionConnection(ViewRootImpl.this));
- }
}
}
@@ -6620,6 +6625,19 @@ public final class ViewRootImpl implements ViewParent,
}
}
+ final class HighContrastTextManager implements HighTextContrastChangeListener {
+ HighContrastTextManager() {
+ mAttachInfo.mHighContrastText = mAccessibilityManager.isHighTextContrastEnabled();
+ }
+ @Override
+ public void onHighTextContrastStateChanged(boolean enabled) {
+ mAttachInfo.mHighContrastText = enabled;
+
+ // Destroy Displaylists so they can be recreated with high contrast recordings
+ destroyHardwareResources();
+ }
+ }
+
/**
* This class is an interface this ViewAncestor provides to the
* AccessibilityManagerService to the latter can interact with
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index cbc38c6..94e2c0e 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -18,6 +18,7 @@ package android.view.accessibility;
import android.Manifest;
import android.accessibilityservice.AccessibilityServiceInfo;
+import android.annotation.NonNull;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
@@ -76,6 +77,9 @@ public final class AccessibilityManager {
public static final int STATE_FLAG_TOUCH_EXPLORATION_ENABLED = 0x00000002;
/** @hide */
+ public static final int STATE_FLAG_HIGH_TEXT_CONTRAST_ENABLED = 0x00000004;
+
+ /** @hide */
public static final int INVERSION_DISABLED = -1;
/** @hide */
@@ -127,13 +131,19 @@ public final class AccessibilityManager {
boolean mIsTouchExplorationEnabled;
+ boolean mIsHighTextContrastEnabled;
+
private final CopyOnWriteArrayList<AccessibilityStateChangeListener>
mAccessibilityStateChangeListeners = new CopyOnWriteArrayList<
AccessibilityStateChangeListener>();
private final CopyOnWriteArrayList<TouchExplorationStateChangeListener>
mTouchExplorationStateChangeListeners = new CopyOnWriteArrayList<
- TouchExplorationStateChangeListener>();
+ TouchExplorationStateChangeListener>();
+
+ private final CopyOnWriteArrayList<HighTextContrastChangeListener>
+ mHighTextContrastStateChangeListeners = new CopyOnWriteArrayList<
+ HighTextContrastChangeListener>();
/**
* Listener for the system accessibility state. To listen for changes to the
@@ -166,6 +176,24 @@ public final class AccessibilityManager {
public void onTouchExplorationStateChanged(boolean enabled);
}
+ /**
+ * Listener for the system high text contrast state. To listen for changes to
+ * the high text contrast state on the device, implement this interface and
+ * register it with the system by calling
+ * {@link #addHighTextContrastStateChangeListener}.
+ *
+ * @hide
+ */
+ public interface HighTextContrastChangeListener {
+
+ /**
+ * Called when the high text contrast enabled state changes.
+ *
+ * @param enabled Whether high text contrast is enabled.
+ */
+ public void onHighTextContrastStateChanged(boolean enabled);
+ }
+
private final IAccessibilityManagerClient.Stub mClient =
new IAccessibilityManagerClient.Stub() {
public void setState(int state) {
@@ -262,6 +290,27 @@ public final class AccessibilityManager {
}
/**
+ * Returns if the high text contrast in the system is enabled.
+ * <p>
+ * <strong>Note:</strong> You need to query this only if you application is
+ * doing its own rendering and does not rely on the platform rendering pipeline.
+ * </p>
+ *
+ * @return True if high text contrast is enabled, false otherwise.
+ *
+ * @hide
+ */
+ public boolean isHighTextContrastEnabled() {
+ synchronized (mLock) {
+ IAccessibilityManager service = getServiceLocked();
+ if (service == null) {
+ return false;
+ }
+ return mIsHighTextContrastEnabled;
+ }
+ }
+
+ /**
* Sends an {@link AccessibilityEvent}.
*
* @param event The event to send.
@@ -434,7 +483,7 @@ public final class AccessibilityManager {
* @return True if successfully registered.
*/
public boolean addAccessibilityStateChangeListener(
- AccessibilityStateChangeListener listener) {
+ @NonNull AccessibilityStateChangeListener listener) {
// Final CopyOnArrayList - no lock needed.
return mAccessibilityStateChangeListeners.add(listener);
}
@@ -446,7 +495,7 @@ public final class AccessibilityManager {
* @return True if successfully unregistered.
*/
public boolean removeAccessibilityStateChangeListener(
- AccessibilityStateChangeListener listener) {
+ @NonNull AccessibilityStateChangeListener listener) {
// Final CopyOnArrayList - no lock needed.
return mAccessibilityStateChangeListeners.remove(listener);
}
@@ -459,7 +508,7 @@ public final class AccessibilityManager {
* @return True if successfully registered.
*/
public boolean addTouchExplorationStateChangeListener(
- TouchExplorationStateChangeListener listener) {
+ @NonNull TouchExplorationStateChangeListener listener) {
// Final CopyOnArrayList - no lock needed.
return mTouchExplorationStateChangeListeners.add(listener);
}
@@ -471,12 +520,41 @@ public final class AccessibilityManager {
* @return True if successfully unregistered.
*/
public boolean removeTouchExplorationStateChangeListener(
- TouchExplorationStateChangeListener listener) {
+ @NonNull TouchExplorationStateChangeListener listener) {
// Final CopyOnArrayList - no lock needed.
return mTouchExplorationStateChangeListeners.remove(listener);
}
/**
+ * Registers a {@link HighTextContrastChangeListener} for changes in
+ * the global high text contrast state of the system.
+ *
+ * @param listener The listener.
+ * @return True if successfully registered.
+ *
+ * @hide
+ */
+ public boolean addHighTextContrastStateChangeListener(
+ @NonNull HighTextContrastChangeListener listener) {
+ // Final CopyOnArrayList - no lock needed.
+ return mHighTextContrastStateChangeListeners.add(listener);
+ }
+
+ /**
+ * Unregisters a {@link HighTextContrastChangeListener}.
+ *
+ * @param listener The listener.
+ * @return True if successfully unregistered.
+ *
+ * @hide
+ */
+ public boolean removeHighTextContrastStateChangeListener(
+ @NonNull HighTextContrastChangeListener listener) {
+ // Final CopyOnArrayList - no lock needed.
+ return mHighTextContrastStateChangeListeners.remove(listener);
+ }
+
+ /**
* Sets the current state and notifies listeners, if necessary.
*
* @param stateFlags The state flags.
@@ -485,13 +563,17 @@ public final class AccessibilityManager {
final boolean enabled = (stateFlags & STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
final boolean touchExplorationEnabled =
(stateFlags & STATE_FLAG_TOUCH_EXPLORATION_ENABLED) != 0;
+ final boolean highTextContrastEnabled =
+ (stateFlags & STATE_FLAG_HIGH_TEXT_CONTRAST_ENABLED) != 0;
final boolean wasEnabled = mIsEnabled;
final boolean wasTouchExplorationEnabled = mIsTouchExplorationEnabled;
+ final boolean wasHighTextContrastEnabled = mIsHighTextContrastEnabled;
// Ensure listeners get current state from isZzzEnabled() calls.
mIsEnabled = enabled;
mIsTouchExplorationEnabled = touchExplorationEnabled;
+ mIsHighTextContrastEnabled = highTextContrastEnabled;
if (wasEnabled != enabled) {
mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED);
@@ -500,6 +582,10 @@ public final class AccessibilityManager {
if (wasTouchExplorationEnabled != touchExplorationEnabled) {
mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_EXPLORATION_STATE_CHANGED);
}
+
+ if (wasHighTextContrastEnabled != highTextContrastEnabled) {
+ mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_HIGH_TEXT_CONTRAST_STATE_CHANGED);
+ }
}
/**
@@ -600,9 +686,25 @@ public final class AccessibilityManager {
}
}
+ /**
+ * Notifies the registered {@link HighTextContrastChangeListener}s.
+ */
+ private void handleNotifyHighTextContrastStateChanged() {
+ final boolean isHighTextContrastEnabled;
+ synchronized (mLock) {
+ isHighTextContrastEnabled = mIsHighTextContrastEnabled;
+ }
+ final int listenerCount = mHighTextContrastStateChangeListeners.size();
+ for (int i = 0; i < listenerCount; i++) {
+ mHighTextContrastStateChangeListeners.get(i)
+ .onHighTextContrastStateChanged(isHighTextContrastEnabled);
+ }
+ }
+
private final class MyHandler extends Handler {
public static final int MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED = 1;
public static final int MSG_NOTIFY_EXPLORATION_STATE_CHANGED = 2;
+ public static final int MSG_NOTIFY_HIGH_TEXT_CONTRAST_STATE_CHANGED = 3;
public MyHandler(Looper looper) {
super(looper, null, false);
@@ -617,7 +719,11 @@ public final class AccessibilityManager {
case MSG_NOTIFY_EXPLORATION_STATE_CHANGED: {
handleNotifyTouchExplorationStateChanged();
- }
+ } break;
+
+ case MSG_NOTIFY_HIGH_TEXT_CONTRAST_STATE_CHANGED: {
+ handleNotifyHighTextContrastStateChanged();
+ } break;
}
}
}
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index c352398..8641e73 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -100,6 +100,12 @@ static void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject clazz,
renderer->setViewport(width, height);
}
+static void android_view_GLES20Canvas_setHighContrastText(JNIEnv* env, jobject clazz,
+ jlong rendererPtr, jboolean highContrastText) {
+ DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
+ renderer->setHighContrastText(highContrastText);
+}
+
static int android_view_GLES20Canvas_prepare(JNIEnv* env, jobject clazz,
jlong rendererPtr, jboolean opaque) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
@@ -842,6 +848,7 @@ static JNINativeMethod gMethods[] = {
{ "nDestroyRenderer", "(J)V", (void*) android_view_GLES20Canvas_destroyRenderer },
{ "nSetViewport", "(JII)V", (void*) android_view_GLES20Canvas_setViewport },
+ { "nSetHighContrastText","(JZ)V", (void*) android_view_GLES20Canvas_setHighContrastText },
{ "nPrepare", "(JZ)I", (void*) android_view_GLES20Canvas_prepare },
{ "nPrepareDirty", "(JIIIIZ)I", (void*) android_view_GLES20Canvas_prepareDirty },
{ "nFinish", "(J)V", (void*) android_view_GLES20Canvas_finish },