summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/accessibilityservice/AccessibilityService.java111
-rw-r--r--core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl8
-rw-r--r--core/java/android/view/AccessibilityInteractionController.java9
-rw-r--r--core/java/android/view/View.java18
-rw-r--r--core/java/android/view/ViewGroup.java30
-rw-r--r--core/java/android/view/ViewRootImpl.java8
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java23
7 files changed, 168 insertions, 39 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 3da35d3..eed8aa6 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -259,13 +259,51 @@ 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: {
@@ -402,6 +480,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
* to change some of the dynamically configurable properties at
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 30da9db..1bd5387 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -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);
}
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 6c1a6bf..54c62ee 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -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
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6c1f02d..500b966 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -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()) {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 7e90e2b..30ea766 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5723,11 +5723,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
throw new IllegalStateException("Instance already recycled.");
}
clear();
- if (sPoolSize < MAX_POOL_SIZE) {
- mNext = sPool;
- mIsPooled = true;
- sPool = this;
- sPoolSize++;
+ synchronized (sPoolLock) {
+ if (sPoolSize < MAX_POOL_SIZE) {
+ mNext = sPool;
+ mIsPooled = true;
+ sPool = this;
+ sPoolSize++;
+ }
}
}
@@ -5820,11 +5822,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
throw new IllegalStateException("Instance already recycled.");
}
clear();
- if (sPoolSize < MAX_POOL_SIZE) {
- mNext = sPool;
- mIsPooled = true;
- sPool = this;
- sPoolSize++;
+ synchronized (sPoolLock) {
+ if (sPoolSize < MAX_POOL_SIZE) {
+ mNext = sPool;
+ mIsPooled = true;
+ sPool = this;
+ sPoolSize++;
+ }
}
}
@@ -5874,9 +5878,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (widthDiference != 0) {
return -widthDiference;
}
- // Return nondeterministically one of them since we do
- // not want to ignore any views.
- return 1;
+ // Just break the tie somehow. The accessibliity ids are unique
+ // and stable, hence this is deterministic tie breaking.
+ return mView.getAccessibilityViewId() - another.mView.getAccessibilityViewId();
}
private void init(ViewGroup root, View view) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index b4554d5..a1e33ac 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2665,6 +2665,7 @@ public final class ViewRootImpl implements ViewParent,
private final static int MSG_PROCESS_INPUT_EVENTS = 19;
private final static int MSG_DISPATCH_SCREEN_STATE = 20;
private final static int MSG_INVALIDATE_DISPLAY_LIST = 21;
+ private final static int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 22;
final class ViewRootHandler extends Handler {
@Override
@@ -2712,6 +2713,8 @@ public final class ViewRootImpl implements ViewParent,
return "MSG_DISPATCH_SCREEN_STATE";
case MSG_INVALIDATE_DISPLAY_LIST:
return "MSG_INVALIDATE_DISPLAY_LIST";
+ case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST:
+ return "MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST";
}
return super.getMessageName(message);
}
@@ -2921,6 +2924,9 @@ public final class ViewRootImpl implements ViewParent,
case MSG_INVALIDATE_DISPLAY_LIST: {
invalidateDisplayLists();
} break;
+ case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: {
+ setAccessibilityFocusedHost(null);
+ } break;
}
}
}
@@ -5063,7 +5069,7 @@ public final class ViewRootImpl implements ViewParent,
}
} else {
ensureNoConnection();
- setAccessibilityFocusedHost(null);
+ mHandler.obtainMessage(MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST).sendToTarget();
}
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 1071c65..c5f2062 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -84,7 +84,7 @@ public class AccessibilityNodeInfo implements Parcelable {
/**
* Action that gives input focus to the node.
*/
- public static final int ACTION_FOCUS = 0x00000001;
+ public static final int ACTION_FOCUS = 0x00000001;
/**
* Action that clears input focus of the node.
@@ -102,19 +102,24 @@ public class AccessibilityNodeInfo implements Parcelable {
public static final int ACTION_CLEAR_SELECTION = 0x00000008;
/**
- * Action that gives accessibility focus to the node.
+ * Action that clicks on the node info.
*/
- public static final int ACTION_ACCESSIBILITY_FOCUS = 0x00000010;
+ public static final int ACTION_CLICK = 0x00000010;
/**
- * Action that clears accessibility focus of the node.
+ * Action that clicks on the node.
+ */
+ public static final int ACTION_LONG_CLICK = 0x00000020;
+
+ /**
+ * Action that gives accessibility focus to the node.
*/
- public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 0x00000020;
+ public static final int ACTION_ACCESSIBILITY_FOCUS = 0x00000040;
/**
- * Action that clicks on the node info./AccessibilityNodeInfoCache.java
+ * Action that clears accessibility focus of the node.
*/
- public static final int ACTION_CLICK = 0x00000040;
+ public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 0x00000080;
/**
* The input focus.
@@ -278,9 +283,9 @@ public class AccessibilityNodeInfo implements Parcelable {
(root != null) ? root.getAccessibilityViewId() : UNDEFINED;
mSourceNodeId = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
}
-
+
/**
- * Find the view that has the input focus. The search starts from
+ * Find the view that has the specified focus type. The search starts from
* the view represented by this node info.
*
* @param focus The focus to find. One of {@link #FOCUS_INPUT} or