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

Commit 35bfedea authored by Svetoslav Ganov's avatar Svetoslav Ganov
Browse files

Touch exploration separate setting and API to poll the latter state.

1. Seperated touch exploration to be a seperate setting rather being
   magically enabled by the system of accessiiblity is on the there
   is at leas one accessibility service that speaks enabled. Now
   there is a setting for requesting touch exploration but still the
   system will enabled it only if that makes sense i.e. accessibility
   is on and one accessibility service that speaks is enabled.

2. Added public API for checking of touch exploration is enabled.

3. Added description attribute in accessibility service declaration
   which will be shown to the user before enabling the service.

4. Added API for quick cloning of AccessibilityNodeInfo.

5. Added clone functionality to SparseArray, SparseIntArray, and
   SparseBooleanArray.

bug:5034010
bug:5033928

Change-Id: Ia442edbe55c20309244061cd9d24e0545c01b54f
parent d94b71de
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -1823,6 +1823,7 @@ package android.accessibilityservice {
    method public static java.lang.String feedbackTypeToString(int);
    method public static java.lang.String flagToString(int);
    method public boolean getCanRetrieveWindowContent();
    method public java.lang.String getDescription();
    method public java.lang.String getId();
    method public android.content.pm.ResolveInfo getResolveInfo();
    method public java.lang.String getSettingsActivityName();
@@ -16702,6 +16703,7 @@ package android.provider {
    field public static final java.lang.String SELECTED_INPUT_METHOD_SUBTYPE = "selected_input_method_subtype";
    field public static final java.lang.String SETTINGS_CLASSNAME = "settings_classname";
    field public static final java.lang.String SYS_PROP_SETTING_VERSION = "sys.settings_secure_version";
    field public static final java.lang.String TOUCH_EXPLORATION_REQUESTED = "touch_exploration_requested";
    field public static final java.lang.String TTS_DEFAULT_COUNTRY = "tts_default_country";
    field public static final java.lang.String TTS_DEFAULT_LANG = "tts_default_lang";
    field public static final java.lang.String TTS_DEFAULT_PITCH = "tts_default_pitch";
@@ -20731,11 +20733,12 @@ package android.util {
    method public void set(T, V);
  }
  public class SparseArray {
  public class SparseArray implements java.lang.Cloneable {
    ctor public SparseArray();
    ctor public SparseArray(int);
    method public void append(int, E);
    method public void clear();
    method public android.util.SparseArray<E> clone();
    method public void delete(int);
    method public E get(int);
    method public E get(int, E);
@@ -20750,11 +20753,12 @@ package android.util {
    method public E valueAt(int);
  }
  public class SparseBooleanArray {
  public class SparseBooleanArray implements java.lang.Cloneable {
    ctor public SparseBooleanArray();
    ctor public SparseBooleanArray(int);
    method public void append(int, boolean);
    method public void clear();
    method public android.util.SparseBooleanArray clone();
    method public void delete(int);
    method public boolean get(int);
    method public boolean get(int, boolean);
@@ -20766,11 +20770,12 @@ package android.util {
    method public boolean valueAt(int);
  }
  public class SparseIntArray {
  public class SparseIntArray implements java.lang.Cloneable {
    ctor public SparseIntArray();
    ctor public SparseIntArray(int);
    method public void append(int, int);
    method public void clear();
    method public android.util.SparseIntArray clone();
    method public void delete(int);
    method public int get(int);
    method public int get(int, int);
@@ -23265,6 +23270,7 @@ package android.view.accessibility {
    method public java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getInstalledAccessibilityServiceList();
    method public void interrupt();
    method public boolean isEnabled();
    method public boolean isTouchExplorationEnabled();
    method public boolean removeAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener);
    method public void sendAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
  }
@@ -23301,6 +23307,7 @@ package android.view.accessibility {
    method public boolean isSelected();
    method public static android.view.accessibility.AccessibilityNodeInfo obtain(android.view.View);
    method public static android.view.accessibility.AccessibilityNodeInfo obtain();
    method public static android.view.accessibility.AccessibilityNodeInfo obtain(android.view.accessibility.AccessibilityNodeInfo);
    method public boolean performAction(int);
    method public void recycle();
    method public void setBoundsInParent(android.graphics.Rect);
+21 −0
Original line number Diff line number Diff line
@@ -170,6 +170,11 @@ public class AccessibilityServiceInfo implements Parcelable {
     */
    private boolean mCanRetrieveWindowContent;

    /**
     * Description of the accessibility service.
     */
    private String mDescription;

    /**
     * Creates a new instance.
     */
@@ -240,6 +245,8 @@ public class AccessibilityServiceInfo implements Parcelable {
            mCanRetrieveWindowContent = asAttributes.getBoolean(
                    com.android.internal.R.styleable.AccessibilityService_canRetrieveWindowContent,
                    false);
            mDescription = asAttributes.getString(
                    com.android.internal.R.styleable.AccessibilityService_description);
            asAttributes.recycle();
        } catch (NameNotFoundException e) {
            throw new XmlPullParserException( "Unable to create context for: "
@@ -312,6 +319,18 @@ public class AccessibilityServiceInfo implements Parcelable {
        return mCanRetrieveWindowContent;
    }

    /**
     * Description of the accessibility service.
     * <p>
     *    <strong>Statically set from
     *    {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
     * </p>
     * @return The description.
     */
    public String getDescription() {
        return mDescription;
    }

    /**
     * {@inheritDoc}
     */
@@ -329,6 +348,7 @@ public class AccessibilityServiceInfo implements Parcelable {
        parcel.writeParcelable(mResolveInfo, 0);
        parcel.writeString(mSettingsActivityName);
        parcel.writeInt(mCanRetrieveWindowContent ? 1 : 0);
        parcel.writeString(mDescription);
    }

    private void initFromParcel(Parcel parcel) {
@@ -341,6 +361,7 @@ public class AccessibilityServiceInfo implements Parcelable {
        mResolveInfo = parcel.readParcelable(null);
        mSettingsActivityName = parcel.readString();
        mCanRetrieveWindowContent = (parcel.readInt() == 1);
        mDescription = parcel.readString();
    }

    @Override
+7 −0
Original line number Diff line number Diff line
@@ -2682,6 +2682,13 @@ public final class Settings {
         */
        public static final String ACCESSIBILITY_ENABLED = "accessibility_enabled";

        /**
         * If touch exploration is requested. Touch exploration is enabled if it is
         * requested by this setting, accessibility is enabled and there is at least
         * one enabled accessibility serivce that provides spoken feedback.
         */
        public static final String TOUCH_EXPLORATION_REQUESTED = "touch_exploration_requested";

        /**
         * List of the enabled accessibility providers.
         */
+21 −17
Original line number Diff line number Diff line
@@ -23,10 +23,14 @@ import com.android.internal.util.ArrayUtils;
 * there can be gaps in the indices.  It is intended to be more efficient
 * than using a HashMap to map Integers to Objects.
 */
public class SparseArray<E> {
public class SparseArray<E> implements Cloneable {
    private static final Object DELETED = new Object();
    private boolean mGarbage = false;

    private int[] mKeys;
    private Object[] mValues;
    private int mSize;

    /**
     * Creates a new SparseArray containing no mappings.
     */
@@ -47,6 +51,20 @@ public class SparseArray<E> {
        mSize = 0;
    }

    @Override
    @SuppressWarnings("unchecked")
    public SparseArray<E> clone() {
        SparseArray<E> clone = null;
        try {
            clone = (SparseArray<E>) super.clone();
            clone.mKeys = mKeys.clone();
            clone.mValues = mValues.clone();
        } catch (CloneNotSupportedException cnse) {
            /* ignore */
        }
        return clone;
    }

    /**
     * Gets the Object mapped from the specified key, or <code>null</code>
     * if no such mapping has been made.
@@ -59,6 +77,7 @@ public class SparseArray<E> {
     * Gets the Object mapped from the specified key, or the specified Object
     * if no such mapping has been made.
     */
    @SuppressWarnings("unchecked")
    public E get(int key, E valueIfKeyNotFound) {
        int i = binarySearch(mKeys, 0, mSize, key);

@@ -209,6 +228,7 @@ public class SparseArray<E> {
     * the value from the <code>index</code>th key-value mapping that this
     * SparseArray stores.  
     */
    @SuppressWarnings("unchecked")
    public E valueAt(int index) {
        if (mGarbage) {
            gc();
@@ -331,20 +351,4 @@ public class SparseArray<E> {
        else
            return ~high;
    }

    private void checkIntegrity() {
        for (int i = 1; i < mSize; i++) {
            if (mKeys[i] <= mKeys[i - 1]) {
                for (int j = 0; j < mSize; j++) {
                    Log.e("FAIL", j + ": " + mKeys[j] + " -> " + mValues[j]);
                }

                throw new RuntimeException();
            }
        }
    }

    private int[] mKeys;
    private Object[] mValues;
    private int mSize;
}
+14 −13
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ import com.android.internal.util.ArrayUtils;
 * there can be gaps in the indices.  It is intended to be more efficient
 * than using a HashMap to map Integers to Booleans.
 */
public class SparseBooleanArray {
public class SparseBooleanArray implements Cloneable {
    /**
     * Creates a new SparseBooleanArray containing no mappings.
     */
@@ -45,6 +45,19 @@ public class SparseBooleanArray {
        mSize = 0;
    }

    @Override
    public SparseBooleanArray clone() {
        SparseBooleanArray clone = null;
        try {
            clone = (SparseBooleanArray) super.clone();
            clone.mKeys = mKeys.clone();
            clone.mValues = mValues.clone();
        } catch (CloneNotSupportedException cnse) {
            /* ignore */
        }
        return clone;
    }

    /**
     * Gets the boolean mapped from the specified key, or <code>false</code>
     * if no such mapping has been made.
@@ -227,18 +240,6 @@ public class SparseBooleanArray {
            return ~high;
    }

    private void checkIntegrity() {
        for (int i = 1; i < mSize; i++) {
            if (mKeys[i] <= mKeys[i - 1]) {
                for (int j = 0; j < mSize; j++) {
                    Log.e("FAIL", j + ": " + mKeys[j] + " -> " + mValues[j]);
                }

                throw new RuntimeException();
            }
        }
    }

    private int[] mKeys;
    private boolean[] mValues;
    private int mSize;
Loading