diff options
author | Chris Craik <ccraik@google.com> | 2014-07-17 01:26:50 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-07-16 21:54:23 +0000 |
commit | 889fc94ffa70633e510e812b9da86723f4eee384 (patch) | |
tree | ab61f2bcf47dae1f616ec15ad729ba2520dfd133 /core | |
parent | 98b270309a342be0971320c5731f495a901ca4e4 (diff) | |
parent | cce47eb580d666ead1f6095d1e3b65233592bbaa (diff) | |
download | frameworks_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.java | 9 | ||||
-rw-r--r-- | core/java/android/view/GLES20Canvas.java | 10 | ||||
-rw-r--r-- | core/java/android/view/View.java | 6 | ||||
-rw-r--r-- | core/java/android/view/ViewRootImpl.java | 32 | ||||
-rw-r--r-- | core/java/android/view/accessibility/AccessibilityManager.java | 118 | ||||
-rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 7 |
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 }, |