Loading core/java/android/provider/Settings.java +9 −0 Original line number Original line Diff line number Diff line Loading @@ -3677,6 +3677,14 @@ public final class Settings { */ */ public static final String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password"; 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 * If injection of accessibility enhancing JavaScript screen-reader * is enabled. * is enabled. Loading Loading @@ -4644,6 +4652,7 @@ public final class Settings { TOUCH_EXPLORATION_ENABLED, TOUCH_EXPLORATION_ENABLED, ACCESSIBILITY_ENABLED, ACCESSIBILITY_ENABLED, ACCESSIBILITY_SPEAK_PASSWORD, ACCESSIBILITY_SPEAK_PASSWORD, ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, ACCESSIBILITY_CAPTIONING_ENABLED, ACCESSIBILITY_CAPTIONING_ENABLED, ACCESSIBILITY_CAPTIONING_LOCALE, ACCESSIBILITY_CAPTIONING_LOCALE, ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, Loading core/java/android/view/GLES20Canvas.java +9 −1 Original line number Original line Diff line number Diff line Loading @@ -168,7 +168,15 @@ class GLES20Canvas extends HardwareCanvas { nSetViewport(mRenderer, width, height); 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 @Override public int onPreDraw(Rect dirty) { public int onPreDraw(Rect dirty) { Loading core/java/android/view/View.java +6 −0 Original line number Original line Diff line number Diff line Loading @@ -13746,6 +13746,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, int layerType = getLayerType(); int layerType = getLayerType(); final HardwareCanvas canvas = renderNode.start(width, height); final HardwareCanvas canvas = renderNode.start(width, height); canvas.setHighContrastText(mAttachInfo.mHighContrastText); try { try { final HardwareLayer layer = getHardwareLayer(); final HardwareLayer layer = getHardwareLayer(); Loading Loading @@ -19912,6 +19913,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ */ boolean mViewScrollChanged; boolean mViewScrollChanged; /** * Set to true if high contrast mode enabled */ boolean mHighContrastText; /** /** * Global to the view hierarchy used as a temporary for dealing with * Global to the view hierarchy used as a temporary for dealing with * x/y points in the transparent region computations. * x/y points in the transparent region computations. core/java/android/view/ViewRootImpl.java +25 −7 Original line number Original line Diff line number Diff line Loading @@ -63,6 +63,7 @@ import android.view.View.MeasureSpec; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener; import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener; import android.view.accessibility.AccessibilityManager.HighTextContrastChangeListener; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeProvider; import android.view.accessibility.AccessibilityNodeProvider; import android.view.accessibility.IAccessibilityInteractionConnection; import android.view.accessibility.IAccessibilityInteractionConnection; Loading Loading @@ -313,6 +314,7 @@ public final class ViewRootImpl implements ViewParent, AccessibilityInteractionController mAccessibilityInteractionController; AccessibilityInteractionController mAccessibilityInteractionController; AccessibilityInteractionConnectionManager mAccessibilityInteractionConnectionManager; AccessibilityInteractionConnectionManager mAccessibilityInteractionConnectionManager; HighContrastTextManager mHighContrastTextManager; SendWindowContentChangedAccessibilityEvent mSendWindowContentChangedAccessibilityEvent; SendWindowContentChangedAccessibilityEvent mSendWindowContentChangedAccessibilityEvent; Loading Loading @@ -370,12 +372,15 @@ public final class ViewRootImpl implements ViewParent, mPreviousTransparentRegion = new Region(); mPreviousTransparentRegion = new Region(); mFirst = true; // true for the first time the view is added mFirst = true; // true for the first time the view is added mAdded = false; mAdded = false; mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this); mAccessibilityManager = AccessibilityManager.getInstance(context); mAccessibilityManager = AccessibilityManager.getInstance(context); mAccessibilityInteractionConnectionManager = mAccessibilityInteractionConnectionManager = new AccessibilityInteractionConnectionManager(); new AccessibilityInteractionConnectionManager(); mAccessibilityManager.addAccessibilityStateChangeListener( mAccessibilityManager.addAccessibilityStateChangeListener( mAccessibilityInteractionConnectionManager); mAccessibilityInteractionConnectionManager); mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this); mHighContrastTextManager = new HighContrastTextManager(); mAccessibilityManager.addHighTextContrastStateChangeListener( mHighContrastTextManager); mViewConfiguration = ViewConfiguration.get(context); mViewConfiguration = ViewConfiguration.get(context); mDensity = context.getResources().getDisplayMetrics().densityDpi; mDensity = context.getResources().getDisplayMetrics().densityDpi; mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi; mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi; Loading Loading @@ -2914,6 +2919,8 @@ public final class ViewRootImpl implements ViewParent, mAccessibilityInteractionConnectionManager.ensureNoConnection(); mAccessibilityInteractionConnectionManager.ensureNoConnection(); mAccessibilityManager.removeAccessibilityStateChangeListener( mAccessibilityManager.removeAccessibilityStateChangeListener( mAccessibilityInteractionConnectionManager); mAccessibilityInteractionConnectionManager); mAccessibilityManager.removeHighTextContrastStateChangeListener( mHighContrastTextManager); removeSendWindowContentChangedCallback(); removeSendWindowContentChangedCallback(); destroyHardwareRenderer(); destroyHardwareRenderer(); Loading Loading @@ -6585,7 +6592,7 @@ public final class ViewRootImpl implements ViewParent, public void onAccessibilityStateChanged(boolean enabled) { public void onAccessibilityStateChanged(boolean enabled) { if (enabled) { if (enabled) { ensureConnection(); ensureConnection(); if (mAttachInfo != null && mAttachInfo.mHasWindowFocus) { if (mAttachInfo.mHasWindowFocus) { mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); View focusedView = mView.findFocus(); View focusedView = mView.findFocus(); if (focusedView != null && focusedView != mView) { if (focusedView != null && focusedView != mView) { Loading @@ -6599,7 +6606,6 @@ public final class ViewRootImpl implements ViewParent, } } public void ensureConnection() { public void ensureConnection() { if (mAttachInfo != null) { final boolean registered = final boolean registered = mAttachInfo.mAccessibilityWindowId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID; mAttachInfo.mAccessibilityWindowId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID; if (!registered) { if (!registered) { Loading @@ -6608,7 +6614,6 @@ public final class ViewRootImpl implements ViewParent, new AccessibilityInteractionConnection(ViewRootImpl.this)); new AccessibilityInteractionConnection(ViewRootImpl.this)); } } } } } public void ensureNoConnection() { public void ensureNoConnection() { final boolean registered = final boolean registered = Loading @@ -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 * This class is an interface this ViewAncestor provides to the * AccessibilityManagerService to the latter can interact with * AccessibilityManagerService to the latter can interact with Loading core/java/android/view/accessibility/AccessibilityManager.java +112 −6 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.view.accessibility; import android.Manifest; import android.Manifest; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.AccessibilityServiceInfo; import android.annotation.NonNull; import android.content.Context; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.content.pm.ServiceInfo; Loading Loading @@ -75,6 +76,9 @@ public final class AccessibilityManager { /** @hide */ /** @hide */ public static final int STATE_FLAG_TOUCH_EXPLORATION_ENABLED = 0x00000002; public static final int STATE_FLAG_TOUCH_EXPLORATION_ENABLED = 0x00000002; /** @hide */ public static final int STATE_FLAG_HIGH_TEXT_CONTRAST_ENABLED = 0x00000004; /** @hide */ /** @hide */ public static final int INVERSION_DISABLED = -1; public static final int INVERSION_DISABLED = -1; Loading Loading @@ -127,6 +131,8 @@ public final class AccessibilityManager { boolean mIsTouchExplorationEnabled; boolean mIsTouchExplorationEnabled; boolean mIsHighTextContrastEnabled; private final CopyOnWriteArrayList<AccessibilityStateChangeListener> private final CopyOnWriteArrayList<AccessibilityStateChangeListener> mAccessibilityStateChangeListeners = new CopyOnWriteArrayList< mAccessibilityStateChangeListeners = new CopyOnWriteArrayList< AccessibilityStateChangeListener>(); AccessibilityStateChangeListener>(); Loading @@ -135,6 +141,10 @@ public final class AccessibilityManager { mTouchExplorationStateChangeListeners = new CopyOnWriteArrayList< 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 * Listener for the system accessibility state. To listen for changes to the * accessibility state on the device, implement this interface and register * accessibility state on the device, implement this interface and register Loading Loading @@ -166,6 +176,24 @@ public final class AccessibilityManager { public void onTouchExplorationStateChanged(boolean enabled); 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 = private final IAccessibilityManagerClient.Stub mClient = new IAccessibilityManagerClient.Stub() { new IAccessibilityManagerClient.Stub() { public void setState(int state) { public void setState(int state) { Loading Loading @@ -261,6 +289,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}. * Sends an {@link AccessibilityEvent}. * * Loading Loading @@ -434,7 +483,7 @@ public final class AccessibilityManager { * @return True if successfully registered. * @return True if successfully registered. */ */ public boolean addAccessibilityStateChangeListener( public boolean addAccessibilityStateChangeListener( AccessibilityStateChangeListener listener) { @NonNull AccessibilityStateChangeListener listener) { // Final CopyOnArrayList - no lock needed. // Final CopyOnArrayList - no lock needed. return mAccessibilityStateChangeListeners.add(listener); return mAccessibilityStateChangeListeners.add(listener); } } Loading @@ -446,7 +495,7 @@ public final class AccessibilityManager { * @return True if successfully unregistered. * @return True if successfully unregistered. */ */ public boolean removeAccessibilityStateChangeListener( public boolean removeAccessibilityStateChangeListener( AccessibilityStateChangeListener listener) { @NonNull AccessibilityStateChangeListener listener) { // Final CopyOnArrayList - no lock needed. // Final CopyOnArrayList - no lock needed. return mAccessibilityStateChangeListeners.remove(listener); return mAccessibilityStateChangeListeners.remove(listener); } } Loading @@ -459,7 +508,7 @@ public final class AccessibilityManager { * @return True if successfully registered. * @return True if successfully registered. */ */ public boolean addTouchExplorationStateChangeListener( public boolean addTouchExplorationStateChangeListener( TouchExplorationStateChangeListener listener) { @NonNull TouchExplorationStateChangeListener listener) { // Final CopyOnArrayList - no lock needed. // Final CopyOnArrayList - no lock needed. return mTouchExplorationStateChangeListeners.add(listener); return mTouchExplorationStateChangeListeners.add(listener); } } Loading @@ -471,11 +520,40 @@ public final class AccessibilityManager { * @return True if successfully unregistered. * @return True if successfully unregistered. */ */ public boolean removeTouchExplorationStateChangeListener( public boolean removeTouchExplorationStateChangeListener( TouchExplorationStateChangeListener listener) { @NonNull TouchExplorationStateChangeListener listener) { // Final CopyOnArrayList - no lock needed. // Final CopyOnArrayList - no lock needed. return mTouchExplorationStateChangeListeners.remove(listener); 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. * Sets the current state and notifies listeners, if necessary. * * Loading @@ -485,13 +563,17 @@ public final class AccessibilityManager { final boolean enabled = (stateFlags & STATE_FLAG_ACCESSIBILITY_ENABLED) != 0; final boolean enabled = (stateFlags & STATE_FLAG_ACCESSIBILITY_ENABLED) != 0; final boolean touchExplorationEnabled = final boolean touchExplorationEnabled = (stateFlags & STATE_FLAG_TOUCH_EXPLORATION_ENABLED) != 0; (stateFlags & STATE_FLAG_TOUCH_EXPLORATION_ENABLED) != 0; final boolean highTextContrastEnabled = (stateFlags & STATE_FLAG_HIGH_TEXT_CONTRAST_ENABLED) != 0; final boolean wasEnabled = mIsEnabled; final boolean wasEnabled = mIsEnabled; final boolean wasTouchExplorationEnabled = mIsTouchExplorationEnabled; final boolean wasTouchExplorationEnabled = mIsTouchExplorationEnabled; final boolean wasHighTextContrastEnabled = mIsHighTextContrastEnabled; // Ensure listeners get current state from isZzzEnabled() calls. // Ensure listeners get current state from isZzzEnabled() calls. mIsEnabled = enabled; mIsEnabled = enabled; mIsTouchExplorationEnabled = touchExplorationEnabled; mIsTouchExplorationEnabled = touchExplorationEnabled; mIsHighTextContrastEnabled = highTextContrastEnabled; if (wasEnabled != enabled) { if (wasEnabled != enabled) { mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED); mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED); Loading @@ -500,6 +582,10 @@ public final class AccessibilityManager { if (wasTouchExplorationEnabled != touchExplorationEnabled) { if (wasTouchExplorationEnabled != touchExplorationEnabled) { mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_EXPLORATION_STATE_CHANGED); mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_EXPLORATION_STATE_CHANGED); } } if (wasHighTextContrastEnabled != highTextContrastEnabled) { mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_HIGH_TEXT_CONTRAST_STATE_CHANGED); } } } /** /** Loading Loading @@ -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 { private final class MyHandler extends Handler { public static final int MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED = 1; 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_EXPLORATION_STATE_CHANGED = 2; public static final int MSG_NOTIFY_HIGH_TEXT_CONTRAST_STATE_CHANGED = 3; public MyHandler(Looper looper) { public MyHandler(Looper looper) { super(looper, null, false); super(looper, null, false); Loading @@ -617,7 +719,11 @@ public final class AccessibilityManager { case MSG_NOTIFY_EXPLORATION_STATE_CHANGED: { case MSG_NOTIFY_EXPLORATION_STATE_CHANGED: { handleNotifyTouchExplorationStateChanged(); handleNotifyTouchExplorationStateChanged(); } } break; case MSG_NOTIFY_HIGH_TEXT_CONTRAST_STATE_CHANGED: { handleNotifyHighTextContrastStateChanged(); } break; } } } } } } Loading Loading
core/java/android/provider/Settings.java +9 −0 Original line number Original line Diff line number Diff line Loading @@ -3677,6 +3677,14 @@ public final class Settings { */ */ public static final String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password"; 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 * If injection of accessibility enhancing JavaScript screen-reader * is enabled. * is enabled. Loading Loading @@ -4644,6 +4652,7 @@ public final class Settings { TOUCH_EXPLORATION_ENABLED, TOUCH_EXPLORATION_ENABLED, ACCESSIBILITY_ENABLED, ACCESSIBILITY_ENABLED, ACCESSIBILITY_SPEAK_PASSWORD, ACCESSIBILITY_SPEAK_PASSWORD, ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, ACCESSIBILITY_CAPTIONING_ENABLED, ACCESSIBILITY_CAPTIONING_ENABLED, ACCESSIBILITY_CAPTIONING_LOCALE, ACCESSIBILITY_CAPTIONING_LOCALE, ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, Loading
core/java/android/view/GLES20Canvas.java +9 −1 Original line number Original line Diff line number Diff line Loading @@ -168,7 +168,15 @@ class GLES20Canvas extends HardwareCanvas { nSetViewport(mRenderer, width, height); 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 @Override public int onPreDraw(Rect dirty) { public int onPreDraw(Rect dirty) { Loading
core/java/android/view/View.java +6 −0 Original line number Original line Diff line number Diff line Loading @@ -13746,6 +13746,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, int layerType = getLayerType(); int layerType = getLayerType(); final HardwareCanvas canvas = renderNode.start(width, height); final HardwareCanvas canvas = renderNode.start(width, height); canvas.setHighContrastText(mAttachInfo.mHighContrastText); try { try { final HardwareLayer layer = getHardwareLayer(); final HardwareLayer layer = getHardwareLayer(); Loading Loading @@ -19912,6 +19913,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ */ boolean mViewScrollChanged; boolean mViewScrollChanged; /** * Set to true if high contrast mode enabled */ boolean mHighContrastText; /** /** * Global to the view hierarchy used as a temporary for dealing with * Global to the view hierarchy used as a temporary for dealing with * x/y points in the transparent region computations. * x/y points in the transparent region computations.
core/java/android/view/ViewRootImpl.java +25 −7 Original line number Original line Diff line number Diff line Loading @@ -63,6 +63,7 @@ import android.view.View.MeasureSpec; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener; import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener; import android.view.accessibility.AccessibilityManager.HighTextContrastChangeListener; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeProvider; import android.view.accessibility.AccessibilityNodeProvider; import android.view.accessibility.IAccessibilityInteractionConnection; import android.view.accessibility.IAccessibilityInteractionConnection; Loading Loading @@ -313,6 +314,7 @@ public final class ViewRootImpl implements ViewParent, AccessibilityInteractionController mAccessibilityInteractionController; AccessibilityInteractionController mAccessibilityInteractionController; AccessibilityInteractionConnectionManager mAccessibilityInteractionConnectionManager; AccessibilityInteractionConnectionManager mAccessibilityInteractionConnectionManager; HighContrastTextManager mHighContrastTextManager; SendWindowContentChangedAccessibilityEvent mSendWindowContentChangedAccessibilityEvent; SendWindowContentChangedAccessibilityEvent mSendWindowContentChangedAccessibilityEvent; Loading Loading @@ -370,12 +372,15 @@ public final class ViewRootImpl implements ViewParent, mPreviousTransparentRegion = new Region(); mPreviousTransparentRegion = new Region(); mFirst = true; // true for the first time the view is added mFirst = true; // true for the first time the view is added mAdded = false; mAdded = false; mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this); mAccessibilityManager = AccessibilityManager.getInstance(context); mAccessibilityManager = AccessibilityManager.getInstance(context); mAccessibilityInteractionConnectionManager = mAccessibilityInteractionConnectionManager = new AccessibilityInteractionConnectionManager(); new AccessibilityInteractionConnectionManager(); mAccessibilityManager.addAccessibilityStateChangeListener( mAccessibilityManager.addAccessibilityStateChangeListener( mAccessibilityInteractionConnectionManager); mAccessibilityInteractionConnectionManager); mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this); mHighContrastTextManager = new HighContrastTextManager(); mAccessibilityManager.addHighTextContrastStateChangeListener( mHighContrastTextManager); mViewConfiguration = ViewConfiguration.get(context); mViewConfiguration = ViewConfiguration.get(context); mDensity = context.getResources().getDisplayMetrics().densityDpi; mDensity = context.getResources().getDisplayMetrics().densityDpi; mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi; mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi; Loading Loading @@ -2914,6 +2919,8 @@ public final class ViewRootImpl implements ViewParent, mAccessibilityInteractionConnectionManager.ensureNoConnection(); mAccessibilityInteractionConnectionManager.ensureNoConnection(); mAccessibilityManager.removeAccessibilityStateChangeListener( mAccessibilityManager.removeAccessibilityStateChangeListener( mAccessibilityInteractionConnectionManager); mAccessibilityInteractionConnectionManager); mAccessibilityManager.removeHighTextContrastStateChangeListener( mHighContrastTextManager); removeSendWindowContentChangedCallback(); removeSendWindowContentChangedCallback(); destroyHardwareRenderer(); destroyHardwareRenderer(); Loading Loading @@ -6585,7 +6592,7 @@ public final class ViewRootImpl implements ViewParent, public void onAccessibilityStateChanged(boolean enabled) { public void onAccessibilityStateChanged(boolean enabled) { if (enabled) { if (enabled) { ensureConnection(); ensureConnection(); if (mAttachInfo != null && mAttachInfo.mHasWindowFocus) { if (mAttachInfo.mHasWindowFocus) { mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); View focusedView = mView.findFocus(); View focusedView = mView.findFocus(); if (focusedView != null && focusedView != mView) { if (focusedView != null && focusedView != mView) { Loading @@ -6599,7 +6606,6 @@ public final class ViewRootImpl implements ViewParent, } } public void ensureConnection() { public void ensureConnection() { if (mAttachInfo != null) { final boolean registered = final boolean registered = mAttachInfo.mAccessibilityWindowId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID; mAttachInfo.mAccessibilityWindowId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID; if (!registered) { if (!registered) { Loading @@ -6608,7 +6614,6 @@ public final class ViewRootImpl implements ViewParent, new AccessibilityInteractionConnection(ViewRootImpl.this)); new AccessibilityInteractionConnection(ViewRootImpl.this)); } } } } } public void ensureNoConnection() { public void ensureNoConnection() { final boolean registered = final boolean registered = Loading @@ -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 * This class is an interface this ViewAncestor provides to the * AccessibilityManagerService to the latter can interact with * AccessibilityManagerService to the latter can interact with Loading
core/java/android/view/accessibility/AccessibilityManager.java +112 −6 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.view.accessibility; import android.Manifest; import android.Manifest; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.AccessibilityServiceInfo; import android.annotation.NonNull; import android.content.Context; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.content.pm.ServiceInfo; Loading Loading @@ -75,6 +76,9 @@ public final class AccessibilityManager { /** @hide */ /** @hide */ public static final int STATE_FLAG_TOUCH_EXPLORATION_ENABLED = 0x00000002; public static final int STATE_FLAG_TOUCH_EXPLORATION_ENABLED = 0x00000002; /** @hide */ public static final int STATE_FLAG_HIGH_TEXT_CONTRAST_ENABLED = 0x00000004; /** @hide */ /** @hide */ public static final int INVERSION_DISABLED = -1; public static final int INVERSION_DISABLED = -1; Loading Loading @@ -127,6 +131,8 @@ public final class AccessibilityManager { boolean mIsTouchExplorationEnabled; boolean mIsTouchExplorationEnabled; boolean mIsHighTextContrastEnabled; private final CopyOnWriteArrayList<AccessibilityStateChangeListener> private final CopyOnWriteArrayList<AccessibilityStateChangeListener> mAccessibilityStateChangeListeners = new CopyOnWriteArrayList< mAccessibilityStateChangeListeners = new CopyOnWriteArrayList< AccessibilityStateChangeListener>(); AccessibilityStateChangeListener>(); Loading @@ -135,6 +141,10 @@ public final class AccessibilityManager { mTouchExplorationStateChangeListeners = new CopyOnWriteArrayList< 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 * Listener for the system accessibility state. To listen for changes to the * accessibility state on the device, implement this interface and register * accessibility state on the device, implement this interface and register Loading Loading @@ -166,6 +176,24 @@ public final class AccessibilityManager { public void onTouchExplorationStateChanged(boolean enabled); 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 = private final IAccessibilityManagerClient.Stub mClient = new IAccessibilityManagerClient.Stub() { new IAccessibilityManagerClient.Stub() { public void setState(int state) { public void setState(int state) { Loading Loading @@ -261,6 +289,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}. * Sends an {@link AccessibilityEvent}. * * Loading Loading @@ -434,7 +483,7 @@ public final class AccessibilityManager { * @return True if successfully registered. * @return True if successfully registered. */ */ public boolean addAccessibilityStateChangeListener( public boolean addAccessibilityStateChangeListener( AccessibilityStateChangeListener listener) { @NonNull AccessibilityStateChangeListener listener) { // Final CopyOnArrayList - no lock needed. // Final CopyOnArrayList - no lock needed. return mAccessibilityStateChangeListeners.add(listener); return mAccessibilityStateChangeListeners.add(listener); } } Loading @@ -446,7 +495,7 @@ public final class AccessibilityManager { * @return True if successfully unregistered. * @return True if successfully unregistered. */ */ public boolean removeAccessibilityStateChangeListener( public boolean removeAccessibilityStateChangeListener( AccessibilityStateChangeListener listener) { @NonNull AccessibilityStateChangeListener listener) { // Final CopyOnArrayList - no lock needed. // Final CopyOnArrayList - no lock needed. return mAccessibilityStateChangeListeners.remove(listener); return mAccessibilityStateChangeListeners.remove(listener); } } Loading @@ -459,7 +508,7 @@ public final class AccessibilityManager { * @return True if successfully registered. * @return True if successfully registered. */ */ public boolean addTouchExplorationStateChangeListener( public boolean addTouchExplorationStateChangeListener( TouchExplorationStateChangeListener listener) { @NonNull TouchExplorationStateChangeListener listener) { // Final CopyOnArrayList - no lock needed. // Final CopyOnArrayList - no lock needed. return mTouchExplorationStateChangeListeners.add(listener); return mTouchExplorationStateChangeListeners.add(listener); } } Loading @@ -471,11 +520,40 @@ public final class AccessibilityManager { * @return True if successfully unregistered. * @return True if successfully unregistered. */ */ public boolean removeTouchExplorationStateChangeListener( public boolean removeTouchExplorationStateChangeListener( TouchExplorationStateChangeListener listener) { @NonNull TouchExplorationStateChangeListener listener) { // Final CopyOnArrayList - no lock needed. // Final CopyOnArrayList - no lock needed. return mTouchExplorationStateChangeListeners.remove(listener); 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. * Sets the current state and notifies listeners, if necessary. * * Loading @@ -485,13 +563,17 @@ public final class AccessibilityManager { final boolean enabled = (stateFlags & STATE_FLAG_ACCESSIBILITY_ENABLED) != 0; final boolean enabled = (stateFlags & STATE_FLAG_ACCESSIBILITY_ENABLED) != 0; final boolean touchExplorationEnabled = final boolean touchExplorationEnabled = (stateFlags & STATE_FLAG_TOUCH_EXPLORATION_ENABLED) != 0; (stateFlags & STATE_FLAG_TOUCH_EXPLORATION_ENABLED) != 0; final boolean highTextContrastEnabled = (stateFlags & STATE_FLAG_HIGH_TEXT_CONTRAST_ENABLED) != 0; final boolean wasEnabled = mIsEnabled; final boolean wasEnabled = mIsEnabled; final boolean wasTouchExplorationEnabled = mIsTouchExplorationEnabled; final boolean wasTouchExplorationEnabled = mIsTouchExplorationEnabled; final boolean wasHighTextContrastEnabled = mIsHighTextContrastEnabled; // Ensure listeners get current state from isZzzEnabled() calls. // Ensure listeners get current state from isZzzEnabled() calls. mIsEnabled = enabled; mIsEnabled = enabled; mIsTouchExplorationEnabled = touchExplorationEnabled; mIsTouchExplorationEnabled = touchExplorationEnabled; mIsHighTextContrastEnabled = highTextContrastEnabled; if (wasEnabled != enabled) { if (wasEnabled != enabled) { mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED); mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED); Loading @@ -500,6 +582,10 @@ public final class AccessibilityManager { if (wasTouchExplorationEnabled != touchExplorationEnabled) { if (wasTouchExplorationEnabled != touchExplorationEnabled) { mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_EXPLORATION_STATE_CHANGED); mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_EXPLORATION_STATE_CHANGED); } } if (wasHighTextContrastEnabled != highTextContrastEnabled) { mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_HIGH_TEXT_CONTRAST_STATE_CHANGED); } } } /** /** Loading Loading @@ -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 { private final class MyHandler extends Handler { public static final int MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED = 1; 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_EXPLORATION_STATE_CHANGED = 2; public static final int MSG_NOTIFY_HIGH_TEXT_CONTRAST_STATE_CHANGED = 3; public MyHandler(Looper looper) { public MyHandler(Looper looper) { super(looper, null, false); super(looper, null, false); Loading @@ -617,7 +719,11 @@ public final class AccessibilityManager { case MSG_NOTIFY_EXPLORATION_STATE_CHANGED: { case MSG_NOTIFY_EXPLORATION_STATE_CHANGED: { handleNotifyTouchExplorationStateChanged(); handleNotifyTouchExplorationStateChanged(); } } break; case MSG_NOTIFY_HIGH_TEXT_CONTRAST_STATE_CHANGED: { handleNotifyHighTextContrastStateChanged(); } break; } } } } } } Loading