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

Commit 7650259a authored by Svetoslav Ganov's avatar Svetoslav Ganov
Browse files

Improving accessibility feedback for two state widgets.

1. Added population of sensible text for the state of the
   two state controls such as CheckBox, Switch, etc. This
   is important since if they are in a layout manager which
   fires an accessibility event there should be a description
   of the widget.

bug:5092552

Change-Id: Ie3ca955653563496b84db379ae23a23fe88089a8
parent a31f5e63
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -61,8 +61,7 @@ public class CheckBoxPreference extends TwoStatePreference {
        View checkboxView = view.findViewById(com.android.internal.R.id.checkbox);
        if (checkboxView != null && checkboxView instanceof Checkable) {
            ((Checkable) checkboxView).setChecked(mChecked);
            // Post this so this view is bound and attached when firing the event.
            postSendAccessibilityEventForView(checkboxView);
            sendAccessibilityEvent(checkboxView);
        }

        syncSummaryView(view);
+2 −2
Original line number Diff line number Diff line
@@ -102,8 +102,8 @@ public class SwitchPreference extends TwoStatePreference {
        View checkableView = view.findViewById(com.android.internal.R.id.switchWidget);
        if (checkableView != null && checkableView instanceof Checkable) {
            ((Checkable) checkableView).setChecked(mChecked);
            // Post this so this view is bound and attached when firing the event.
            postSendAccessibilityEventForView(checkableView);

            sendAccessibilityEvent(checkableView);

            if (checkableView instanceof Switch) {
                final Switch switchView = (Switch) checkableView;
+14 −33
Original line number Diff line number Diff line
@@ -37,10 +37,9 @@ public abstract class TwoStatePreference extends Preference {
    private CharSequence mSummaryOn;
    private CharSequence mSummaryOff;
    boolean mChecked;
    private boolean mSendAccessibilityEventViewClickedType;
    private boolean mSendClickAccessibilityEvent;
    private boolean mDisableDependentsState;

    private SendAccessibilityEventTypeViewClicked mSendAccessibilityEventTypeViewClicked;

    public TwoStatePreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
@@ -60,9 +59,7 @@ public abstract class TwoStatePreference extends Preference {

        boolean newValue = !isChecked();

        // in onBindView() an AccessibilityEventViewClickedType is sent to announce the change
        // not sending
        mSendAccessibilityEventViewClickedType = true;
        mSendClickAccessibilityEvent = true;

        if (!callChangeListener(newValue)) {
            return;
@@ -188,26 +185,19 @@ public abstract class TwoStatePreference extends Preference {
                : (Boolean) defaultValue);
    }

    /**
     * Post send an accessibility event for the given view if appropriate.
     *
     * @param view View that should send the event
     */
    void postSendAccessibilityEventForView(View view) {
        // send an event to announce the value change of the state. It is done here
        // because clicking a preference does not immediately change the checked state
        // for example when enabling the WiFi
        if (mSendAccessibilityEventViewClickedType
                && AccessibilityManager.getInstance(getContext()).isEnabled()
                && view.isEnabled()) {
            mSendAccessibilityEventViewClickedType = false;
            if (mSendAccessibilityEventTypeViewClicked == null) {
                mSendAccessibilityEventTypeViewClicked =
                    new SendAccessibilityEventTypeViewClicked();
            }
            mSendAccessibilityEventTypeViewClicked.mView = view;
            view.post(mSendAccessibilityEventTypeViewClicked);
    void sendAccessibilityEvent(View view) {
        // Since the view is still not attached we create, populate,
        // and send the event directly since we do not know when it
        // will be attached and posting commands is not as clean.
        AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(getContext());
        if (mSendClickAccessibilityEvent && accessibilityManager.isEnabled()) {
            AccessibilityEvent event = AccessibilityEvent.obtain();
            event.setEventType(AccessibilityEvent.TYPE_VIEW_CLICKED);
            view.onInitializeAccessibilityEvent(event);
            view.dispatchPopulateAccessibilityEvent(event);
            accessibilityManager.sendAccessibilityEvent(event);
        }
        mSendClickAccessibilityEvent = false;
    }

    /**
@@ -301,13 +291,4 @@ public abstract class TwoStatePreference extends Preference {
            }
        };
    }

    private final class SendAccessibilityEventTypeViewClicked implements Runnable {
        private View mView;

        @Override
        public void run() {
            mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
        }
    }
}
+13 −0
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@ package android.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.view.accessibility.AccessibilityEvent;

import com.android.internal.R;


/**
@@ -65,4 +68,14 @@ public class CheckBox extends CompoundButton {
    public CheckBox(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
        super.onPopulateAccessibilityEvent(event);
        if (isChecked()) {
            event.getText().add(mContext.getString(R.string.checkbox_checked));
        } else {
            event.getText().add(mContext.getString(R.string.checkbox_not_checked));
        }
    }
}
+10 −0
Original line number Diff line number Diff line
@@ -221,4 +221,14 @@ public class CheckedTextView extends TextView implements Checkable {
        super.onInitializeAccessibilityEvent(event);
        event.setChecked(mChecked);
    }

    @Override
    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
        super.onPopulateAccessibilityEvent(event);
        if (isChecked()) {
            event.getText().add(mContext.getString(R.string.radiobutton_selected));
        } else {
            event.getText().add(mContext.getString(R.string.radiobutton_not_selected));
        }
    }
}
Loading