diff options
6 files changed, 47 insertions, 37 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java index 40f45b780485..7e21db3893f6 100644 --- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java @@ -378,6 +378,23 @@ public class AccessibilityServiceInfo implements Parcelable { /** * 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 05b79c1d7a8e..498fa4264fe5 100644 --- a/core/java/android/app/UiAutomation.java +++ b/core/java/android/app/UiAutomation.java @@ -443,18 +443,25 @@ public final class UiAutomation { */ 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 @@ public final class UiAutomation { 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 97c7ff3ea86b..5bc17fae1f9e 100644 --- a/core/java/android/app/UiAutomationConnection.java +++ b/core/java/android/app/UiAutomationConnection.java @@ -158,7 +158,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { 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 14954bea735a..28518aab8ab9 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java @@ -83,6 +83,7 @@ public class AccessibilityNodeInfoCache { } 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 1246051a09bf..9e3f87f447bc 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -8042,7 +8042,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE); } + if (isFocused()) { if (canSelectText()) { info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION); @@ -8655,13 +8656,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ @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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ @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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ @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 2f64908e0506..64dfd67457bc 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -542,7 +542,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { 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 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { 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; } /** |