Merge "Fixing bugs exposed when moving accessibility CTS tests to UiAutomation." into jb-mr2-dev
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 40f45b7..7e21db3 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -378,6 +378,23 @@
/**
* Creates a new instance.
*
+ * @param isAutomation Whether this is a test automation service.
+ *
+ * @hide
+ */
+ public AccessibilityServiceInfo(boolean isAutomation) {
+ // Automation service can do anything.
+ if (isAutomation) {
+ mCapabilities |= CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
+ | CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
+ | CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
+ | CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS;
+ }
+ }
+
+ /**
+ * Creates a new instance.
+ *
* @param resolveInfo The service resolve info.
* @param context Context for accessing resources.
* @throws XmlPullParserException If a XML parsing error occurs.
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 05b79c1..498fa42 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -443,18 +443,25 @@
*/
public AccessibilityEvent executeAndWaitForEvent(Runnable command,
AccessibilityEventFilter filter, long timeoutMillis) throws TimeoutException {
+ // Acquire the lock and prepare for receiving events.
synchronized (mLock) {
throwIfNotConnectedLocked();
-
mEventQueue.clear();
// Prepare to wait for an event.
mWaitingForEventDelivery = true;
+ }
- // We will ignore events from previous interactions.
- final long executionStartTimeMillis = SystemClock.uptimeMillis();
+ // Note: We have to release the lock since calling out with this lock held
+ // can bite. We will correctly filter out events from other interactions,
+ // so starting to collect events before running the action is just fine.
- // Execute the command.
- command.run();
+ // We will ignore events from previous interactions.
+ final long executionStartTimeMillis = SystemClock.uptimeMillis();
+ // Execute the command *without* the lock being held.
+ command.run();
+
+ // Acquire the lock and wait for the event.
+ synchronized (mLock) {
try {
// Wait for the event.
final long startTimeMillis = SystemClock.uptimeMillis();
@@ -463,7 +470,7 @@
while (!mEventQueue.isEmpty()) {
AccessibilityEvent event = mEventQueue.remove(0);
// Ignore events from previous interactions.
- if (event.getEventTime() <= executionStartTimeMillis) {
+ if (event.getEventTime() < executionStartTimeMillis) {
continue;
}
if (filter.accept(event)) {
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index 97c7ff3..5bc17fa 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -158,7 +158,7 @@
private void registerUiTestAutomationServiceLocked(IAccessibilityServiceClient client) {
IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
- AccessibilityServiceInfo info = new AccessibilityServiceInfo();
+ AccessibilityServiceInfo info = new AccessibilityServiceInfo(true);
info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
index 14954be..28518aa 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
@@ -83,6 +83,7 @@
} break;
case AccessibilityEvent.TYPE_VIEW_FOCUSED:
case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED:
+ case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED:
case AccessibilityEvent.TYPE_VIEW_SELECTED:
case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 1246051..9e3f87f 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8042,7 +8042,7 @@
info.setEditable(true);
}
- if (TextUtils.isEmpty(getContentDescription()) && !TextUtils.isEmpty(mText)) {
+ if (!TextUtils.isEmpty(mText)) {
info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY);
info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY);
info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
@@ -8051,6 +8051,7 @@
| AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
| AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
}
+
if (isFocused()) {
if (canSelectText()) {
info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION);
@@ -8655,13 +8656,10 @@
*/
@Override
public CharSequence getIterableTextForAccessibility() {
- if (!TextUtils.isEmpty(mText)) {
- if (!(mText instanceof Spannable)) {
- setText(mText, BufferType.SPANNABLE);
- }
- return mText;
+ if (!(mText instanceof Spannable)) {
+ setText(mText, BufferType.SPANNABLE);
}
- return super.getIterableTextForAccessibility();
+ return mText;
}
/**
@@ -8697,13 +8695,7 @@
*/
@Override
public int getAccessibilitySelectionStart() {
- if (TextUtils.isEmpty(getContentDescription())) {
- final int selectionStart = getSelectionStart();
- if (selectionStart >= 0) {
- return selectionStart;
- }
- }
- return ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
+ return getSelectionStart();
}
/**
@@ -8718,13 +8710,7 @@
*/
@Override
public int getAccessibilitySelectionEnd() {
- if (TextUtils.isEmpty(getContentDescription())) {
- final int selectionEnd = getSelectionEnd();
- if (selectionEnd >= 0) {
- return selectionEnd;
- }
- }
- return ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
+ return getSelectionEnd();
}
/**
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 2f64908..64dfd67 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -542,7 +542,8 @@
return -1;
}
- public void registerUiTestAutomationService(IBinder owner, IAccessibilityServiceClient serviceClient,
+ public void registerUiTestAutomationService(IBinder owner,
+ IAccessibilityServiceClient serviceClient,
AccessibilityServiceInfo accessibilityServiceInfo) {
mSecurityPolicy.enforceCallingPermission(Manifest.permission.RETRIEVE_WINDOW_CONTENT,
FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE);
@@ -1732,14 +1733,12 @@
mFetchFlags &= ~AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS;
}
- if (mResolveInfo != null) {
- mRequestTouchExplorationMode = (info.flags
- & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
- mRequestEnhancedWebAccessibility = (info.flags
- & AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY) != 0;
- mRequestFilterKeyEvents = (info.flags
- & AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS) != 0;
- }
+ mRequestTouchExplorationMode = (info.flags
+ & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
+ mRequestEnhancedWebAccessibility = (info.flags
+ & AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY) != 0;
+ mRequestFilterKeyEvents = (info.flags
+ & AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS) != 0;
}
/**