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

Commit 005b83b0 authored by Svetoslav Ganov's avatar Svetoslav Ganov
Browse files

Adding some more gestures and actions for accessibility.

1. Added more gesture for accessibility. After a meeting
   with the access-eng team we have decided that the current
   set of gestures may be smaller than needed considering
   that we will use four gestures for home, back, recents,
   and notifications.

2. Adding actions for going back, home, opening the recents,
   and opening the notifications.

3. Added preliminary mapping from some of the new gestures
   to the new actions.

4. Fixed a bug in the accessibility interaction controller
   which was trying to create a handled on the main looper
   thread which may be null if the queried UI is in the
   system process. Now the context looper of the root view
   is used.

5. Fixed a bug of using an incorrect constant.

6. Added a missing locking in a couple of places.

7. Fixed view comparison for accessibilityt since it was
   not anisymmetric.

bug:5932640
bug:5605641

Change-Id: Icc983bf4eafefa42b65920b3782ed8a25518e94f
parent b3830f67
Loading
Loading
Loading
Loading
+17 −3
Original line number Diff line number Diff line
@@ -2000,17 +2000,30 @@ package android.accessibilityservice {
    method protected void onGesture(int);
    method public abstract void onInterrupt();
    method protected void onServiceConnected();
    method public final boolean performGlobalAction(int);
    method public final void setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo);
    field public static final int GESTURE_CLOCKWISE_CIRCLE = 9; // 0x9
    field public static final int GESTURE_COUNTER_CLOCKWISE_CIRCLE = 10; // 0xa
    field public static final int GESTURE_SWIPE_DOWN = 2; // 0x2
    field public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 17; // 0x11
    field public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 18; // 0x12
    field public static final int GESTURE_SWIPE_DOWN_AND_UP = 8; // 0x8
    field public static final int GESTURE_SWIPE_LEFT = 3; // 0x3
    field public static final int GESTURE_SWIPE_LEFT_AND_DOWN = 12; // 0xc
    field public static final int GESTURE_SWIPE_LEFT_AND_RIGHT = 5; // 0x5
    field public static final int GESTURE_SWIPE_LEFT_AND_UP = 11; // 0xb
    field public static final int GESTURE_SWIPE_RIGHT = 4; // 0x4
    field public static final int GESTURE_SWIPE_RIGHT_AND_DOWN = 14; // 0xe
    field public static final int GESTURE_SWIPE_RIGHT_AND_LEFT = 6; // 0x6
    field public static final int GESTURE_SWIPE_RIGHT_AND_UP = 13; // 0xd
    field public static final int GESTURE_SWIPE_UP = 1; // 0x1
    field public static final int GESTURE_SWIPE_UP_AND_DOWN = 7; // 0x7
    field public static final int GESTURE_SWIPE_UP_AND_LEFT = 15; // 0xf
    field public static final int GESTURE_SWIPE_UP_AND_RIGHT = 16; // 0x10
    field public static final int GLOBAL_ACTION_BACK = 1; // 0x1
    field public static final int GLOBAL_ACTION_HOME = 2; // 0x2
    field public static final int GLOBAL_ACTION_NOTIFICATIONS = 4; // 0x4
    field public static final int GLOBAL_ACTION_RECENTS = 3; // 0x3
    field public static final java.lang.String SERVICE_INTERFACE = "android.accessibilityservice.AccessibilityService";
    field public static final java.lang.String SERVICE_META_DATA = "android.accessibilityservice";
  }
@@ -24742,12 +24755,13 @@ package android.view.accessibility {
    method public void setSource(android.view.View, int);
    method public void setText(java.lang.CharSequence);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final int ACTION_ACCESSIBILITY_FOCUS = 16; // 0x10
    field public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 32; // 0x20
    field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
    field public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 128; // 0x80
    field public static final int ACTION_CLEAR_FOCUS = 2; // 0x2
    field public static final int ACTION_CLEAR_SELECTION = 8; // 0x8
    field public static final int ACTION_CLICK = 64; // 0x40
    field public static final int ACTION_CLICK = 16; // 0x10
    field public static final int ACTION_FOCUS = 1; // 0x1
    field public static final int ACTION_LONG_CLICK = 32; // 0x20
    field public static final int ACTION_SELECT = 4; // 0x4
    field public static final android.os.Parcelable.Creator CREATOR;
    field public static final int FOCUS_ACCESSIBILITY = 2; // 0x2
+108 −3
Original line number Diff line number Diff line
@@ -258,14 +258,52 @@ public abstract class AccessibilityService extends Service {
     */
    public static final int GESTURE_COUNTER_CLOCKWISE_CIRCLE = 10;

    /**
     * The user has performed a left and up gesture on the touch screen.
     */
    public static final int GESTURE_SWIPE_LEFT_AND_UP = 11;

    /**
     * The user has performed a left and down gesture on the touch screen.
     */
    public static final int GESTURE_SWIPE_LEFT_AND_DOWN = 12;

    /**
     * The user has performed a right and up gesture on the touch screen.
     */
    public static final int GESTURE_SWIPE_RIGHT_AND_UP = 13;

    /**
     * The user has performed a right and down gesture on the touch screen.
     */
    public static final int GESTURE_SWIPE_RIGHT_AND_DOWN = 14;

    /**
     * The user has performed an up and left gesture on the touch screen.
     */
    public static final int GESTURE_SWIPE_UP_AND_LEFT = 15;

    /**
     * The user has performed an up and right gesture on the touch screen.
     */
    public static final int GESTURE_SWIPE_UP_AND_RIGHT = 16;

    /**
     * The user has performed an down and left gesture on the touch screen.
     */
    public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 17;

    /**
     * The user has performed an down and right gesture on the touch screen.
     */
    public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 18;

    /**
     * The {@link Intent} that must be declared as handled by the service.
     */
    public static final String SERVICE_INTERFACE =
        "android.accessibilityservice.AccessibilityService";

    private static final int UNDEFINED = -1;

    /**
     * Name under which an AccessibilityService component publishes information
     * about itself. This meta-data must reference an XML resource containing an
@@ -284,6 +322,28 @@ public abstract class AccessibilityService extends Service {
     */
    public static final String SERVICE_META_DATA = "android.accessibilityservice";

    /**
     * Action to go back.
     */
    public static final int GLOBAL_ACTION_BACK = 1;

    /**
     * Action to go home.
     */
    public static final int GLOBAL_ACTION_HOME = 2;

    /**
     * Action to open the recents.
     */
    public static final int GLOBAL_ACTION_RECENTS = 3;

    /**
     * Action to open the notifications.
     */
    public static final int GLOBAL_ACTION_NOTIFICATIONS = 4;

    private static final int UNDEFINED = -1;

    private static final String LOG_TAG = "AccessibilityService";

    interface Callbacks {
@@ -344,6 +404,22 @@ public abstract class AccessibilityService extends Service {
    protected void onGesture(int gestureId) {
        // TODO: Describe the default gesture processing in the javaDoc once it is finalized.

        // Global actions.
        switch (gestureId) {
            case GESTURE_SWIPE_DOWN_AND_LEFT: {
                performGlobalAction(GLOBAL_ACTION_BACK);
            } return;
            case GESTURE_SWIPE_DOWN_AND_RIGHT: {
                performGlobalAction(GLOBAL_ACTION_HOME);
            } return;
            case GESTURE_SWIPE_UP_AND_LEFT: {
                performGlobalAction(GLOBAL_ACTION_RECENTS);
            } return;
            case GESTURE_SWIPE_UP_AND_RIGHT: {
                performGlobalAction(GLOBAL_ACTION_NOTIFICATIONS);
            } return;
        }

        // Cache the id to avoid locking
        final int connectionId = mConnectionId;
        if (connectionId == UNDEFINED) {
@@ -357,10 +433,12 @@ public abstract class AccessibilityService extends Service {
        if (root == null) {
            return;
        }
        AccessibilityNodeInfo current = root.findFocus(View.FOCUS_ACCESSIBILITY);
        AccessibilityNodeInfo current = root.findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
        if (current == null) {
            current = root;
        }

        // Local actions.
        AccessibilityNodeInfo next = null;
        switch (gestureId) {
            case GESTURE_SWIPE_UP: {
@@ -401,6 +479,33 @@ public abstract class AccessibilityService extends Service {
        }
    }

    /**
     * Performs a global action. Such an action can be performed
     * at any moment regardless of the current application or user
     * location in that application. For example going back, going
     * home, opening recents, etc.
     *
     * @param action The action to perform.
     * @return Whether the action was successfully performed.
     *
     * @see #GLOBAL_ACTION_BACK
     * @see #GLOBAL_ACTION_HOME
     * @see #GLOBAL_ACTION_NOTIFICATIONS
     * @see #GLOBAL_ACTION_RECENTS
     */
    public final boolean performGlobalAction(int action) {
        IAccessibilityServiceConnection connection =
            AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
        if (connection != null) {
            try {
                return connection.perfromGlobalAction(action);
            } catch (RemoteException re) {
                Log.w(LOG_TAG, "Error while calling performGlobalAction", re);
            }
        }
        return false;
    }

    /**
     * Gets the an {@link AccessibilityServiceInfo} describing this
     * {@link AccessibilityService}. This method is useful if one wants
+8 −0
Original line number Diff line number Diff line
@@ -160,4 +160,12 @@ interface IAccessibilityServiceConnection {
     * @return The associated accessibility service info.
     */
    AccessibilityServiceInfo getServiceInfo();

    /**
     * Performs a global action, such as going home, going back, etc.
     *
     * @param action The action to perform.
     * @return Whether the action was performed.
     */
    boolean perfromGlobalAction(int action);
}
+6 −3
Original line number Diff line number Diff line
@@ -52,13 +52,16 @@ final class AccessibilityInteractionController {
    private ArrayList<AccessibilityNodeInfo> mTempAccessibilityNodeInfoList =
        new ArrayList<AccessibilityNodeInfo>();

    private final Handler mHandler = new PrivateHandler();
    private final Handler mHandler;

    private final ViewRootImpl mViewRootImpl;

    private final AccessibilityNodePrefetcher mPrefetcher;

    public AccessibilityInteractionController(ViewRootImpl viewRootImpl) {
        // mView is never null - the caller has already checked.
        Looper looper = viewRootImpl.mView.mContext.getMainLooper();
        mHandler = new PrivateHandler(looper);
        mViewRootImpl = viewRootImpl;
        mPrefetcher = new AccessibilityNodePrefetcher();
    }
@@ -846,8 +849,8 @@ final class AccessibilityInteractionController {
        private final static int MSG_FIND_FOCUS = 5;
        private final static int MSG_FOCUS_SEARCH = 6;

        public PrivateHandler() {
            super(Looper.getMainLooper());
        public PrivateHandler(Looper looper) {
            super(looper);
        }

        @Override
+8 −10
Original line number Diff line number Diff line
@@ -6352,16 +6352,14 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
    public boolean performAccessibilityAction(int action) {
        switch (action) {
            case AccessibilityNodeInfo.ACTION_CLICK: {
                final long now = SystemClock.uptimeMillis();
                // Send down.
                MotionEvent event = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN,
                        getWidth() / 2, getHeight() / 2, 0);
                onTouchEvent(event);
                // Send up.
                event.setAction(MotionEvent.ACTION_UP);
                onTouchEvent(event);
                // Clean up.
                event.recycle();
                if (isClickable()) {
                    performClick();
                }
            } break;
            case AccessibilityNodeInfo.ACTION_LONG_CLICK: {
                if (isLongClickable()) {
                    performLongClick();
                }
            } break;
            case AccessibilityNodeInfo.ACTION_FOCUS: {
                if (!hasFocus()) {
Loading