Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 889fc94f authored by Chris Craik's avatar Chris Craik Committed by Android (Google) Code Review
Browse files

Merge "Add accessibility text contrast setting" into lmp-dev

parents 98b27030 cce47eb5
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -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.
@@ -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,
+9 −1
Original line number Original line Diff line number Diff line
@@ -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) {
+6 −0
Original line number Original line Diff line number Diff line
@@ -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();
@@ -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.
+25 −7
Original line number Original line Diff line number Diff line
@@ -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;
@@ -313,6 +314,7 @@ public final class ViewRootImpl implements ViewParent,
    AccessibilityInteractionController mAccessibilityInteractionController;
    AccessibilityInteractionController mAccessibilityInteractionController;


    AccessibilityInteractionConnectionManager mAccessibilityInteractionConnectionManager;
    AccessibilityInteractionConnectionManager mAccessibilityInteractionConnectionManager;
    HighContrastTextManager mHighContrastTextManager;


    SendWindowContentChangedAccessibilityEvent mSendWindowContentChangedAccessibilityEvent;
    SendWindowContentChangedAccessibilityEvent mSendWindowContentChangedAccessibilityEvent;


@@ -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;
@@ -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();
@@ -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) {
@@ -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) {
@@ -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 =
@@ -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
+112 −6
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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;


@@ -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>();
@@ -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
@@ -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) {
@@ -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}.
     *
     *
@@ -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);
    }
    }
@@ -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);
    }
    }
@@ -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);
    }
    }
@@ -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.
     *
     *
@@ -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);
@@ -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);
        }
    }
    }


    /**
    /**
@@ -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);
@@ -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