Merge "Speedup the accessibility window querying APIs and clean up."
This commit is contained in:
committed by
Android (Google) Code Review
commit
2eecea3b48
@ -14,12 +14,12 @@
|
||||
|
||||
package android.accessibilityservice;
|
||||
|
||||
import com.android.frameworks.coretests.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.frameworks.coretests.R;
|
||||
|
||||
/**
|
||||
* Activity for testing the accessibility APIs for "interrogation" of
|
||||
* the screen content. These APIs allow exploring the screen and
|
||||
|
@ -14,26 +14,21 @@
|
||||
|
||||
package android.accessibilityservice;
|
||||
|
||||
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_FOCUS;
|
||||
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_SELECTION;
|
||||
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_FOCUS;
|
||||
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_FOCUS;
|
||||
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_SELECT;
|
||||
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_SELECTION;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.SystemClock;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.test.suitebuilder.annotation.LargeTest;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityInteractionClient;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.accessibility.IAccessibilityManager;
|
||||
|
||||
import com.android.frameworks.coretests.R;
|
||||
import com.android.internal.util.Predicate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
@ -48,21 +43,15 @@ import java.util.Queue;
|
||||
*/
|
||||
public class InterrogationActivityTest
|
||||
extends ActivityInstrumentationTestCase2<InterrogationActivity> {
|
||||
private static final boolean DEBUG = true;
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static String LOG_TAG = "InterrogationActivityTest";
|
||||
|
||||
// Timeout before give up wait for the system to process an accessibility setting change.
|
||||
private static final int TIMEOUT_PROPAGATE_ACCESSIBLITY_SETTING = 2000;
|
||||
|
||||
// Timeout for the accessibility state of an Activity to be fully initialized.
|
||||
private static final int TIMEOUT_ACCESSIBLITY_STATE_INITIALIZED_MILLIS = 100;
|
||||
private static final int TIMEOUT_PROPAGATE_ACCESSIBILITY_EVENT_MILLIS = 5000;
|
||||
|
||||
// Handle to a connection to the AccessibilityManagerService
|
||||
private static int sConnectionId = View.NO_ID;
|
||||
|
||||
// The last received accessibility event
|
||||
private volatile AccessibilityEvent mLastAccessibilityEvent;
|
||||
private UiTestAutomationBridge mUiTestAutomationBridge;
|
||||
|
||||
public InterrogationActivityTest() {
|
||||
super(InterrogationActivity.class);
|
||||
@ -70,16 +59,39 @@ public class InterrogationActivityTest
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
ensureConnection();
|
||||
bringUpActivityWithInitalizedAccessbility();
|
||||
super.setUp();
|
||||
mUiTestAutomationBridge = new UiTestAutomationBridge();
|
||||
mUiTestAutomationBridge.connect();
|
||||
mUiTestAutomationBridge.executeCommandAndWaitForAccessibilityEvent(new Runnable() {
|
||||
// wait for the first accessibility event
|
||||
@Override
|
||||
public void run() {
|
||||
// bring up the activity
|
||||
getActivity();
|
||||
}
|
||||
},
|
||||
new Predicate<AccessibilityEvent>() {
|
||||
@Override
|
||||
public boolean apply(AccessibilityEvent event) {
|
||||
return (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
|
||||
&& event.getPackageName().equals(getActivity().getPackageName()));
|
||||
}
|
||||
},
|
||||
TIMEOUT_PROPAGATE_ACCESSIBILITY_EVENT_MILLIS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
mUiTestAutomationBridge.disconnect();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
public void testFindAccessibilityNodeInfoByViewId() throws Exception {
|
||||
final long startTimeMillis = SystemClock.uptimeMillis();
|
||||
try {
|
||||
AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
|
||||
AccessibilityNodeInfo button = mUiTestAutomationBridge
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
|
||||
assertNotNull(button);
|
||||
assertEquals(0, button.getChildCount());
|
||||
|
||||
@ -125,8 +137,8 @@ public class InterrogationActivityTest
|
||||
final long startTimeMillis = SystemClock.uptimeMillis();
|
||||
try {
|
||||
// find a view by text
|
||||
List<AccessibilityNodeInfo> buttons = AccessibilityInteractionClient.getInstance()
|
||||
.findAccessibilityNodeInfosByTextInActiveWindow(sConnectionId, "butto");
|
||||
List<AccessibilityNodeInfo> buttons = mUiTestAutomationBridge
|
||||
.findAccessibilityNodeInfosByTextInActiveWindow("butto");
|
||||
assertEquals(9, buttons.size());
|
||||
} finally {
|
||||
if (DEBUG) {
|
||||
@ -141,12 +153,9 @@ public class InterrogationActivityTest
|
||||
public void testFindAccessibilityNodeInfoByViewTextContentDescription() throws Exception {
|
||||
final long startTimeMillis = SystemClock.uptimeMillis();
|
||||
try {
|
||||
bringUpActivityWithInitalizedAccessbility();
|
||||
|
||||
// find a view by text
|
||||
List<AccessibilityNodeInfo> buttons = AccessibilityInteractionClient.getInstance()
|
||||
.findAccessibilityNodeInfosByTextInActiveWindow(sConnectionId,
|
||||
"contentDescription");
|
||||
List<AccessibilityNodeInfo> buttons = mUiTestAutomationBridge
|
||||
.findAccessibilityNodeInfosByTextInActiveWindow("contentDescription");
|
||||
assertEquals(1, buttons.size());
|
||||
} finally {
|
||||
if (DEBUG) {
|
||||
@ -177,8 +186,8 @@ public class InterrogationActivityTest
|
||||
classNameAndTextList.add("android.widget.ButtonButton8");
|
||||
classNameAndTextList.add("android.widget.ButtonButton9");
|
||||
|
||||
AccessibilityNodeInfo root = AccessibilityInteractionClient.getInstance()
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.root);
|
||||
AccessibilityNodeInfo root = mUiTestAutomationBridge
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.root);
|
||||
assertNotNull("We must find the existing root.", root);
|
||||
|
||||
Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>();
|
||||
@ -216,16 +225,16 @@ public class InterrogationActivityTest
|
||||
final long startTimeMillis = SystemClock.uptimeMillis();
|
||||
try {
|
||||
// find a view and make sure it is not focused
|
||||
AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
|
||||
AccessibilityNodeInfo button = mUiTestAutomationBridge
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
|
||||
assertFalse(button.isFocused());
|
||||
|
||||
// focus the view
|
||||
assertTrue(button.performAction(ACTION_FOCUS));
|
||||
|
||||
// find the view again and make sure it is focused
|
||||
button = AccessibilityInteractionClient.getInstance()
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
|
||||
button = mUiTestAutomationBridge
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
|
||||
assertTrue(button.isFocused());
|
||||
} finally {
|
||||
if (DEBUG) {
|
||||
@ -240,24 +249,24 @@ public class InterrogationActivityTest
|
||||
final long startTimeMillis = SystemClock.uptimeMillis();
|
||||
try {
|
||||
// find a view and make sure it is not focused
|
||||
AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
|
||||
AccessibilityNodeInfo button = mUiTestAutomationBridge
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
|
||||
assertFalse(button.isFocused());
|
||||
|
||||
// focus the view
|
||||
assertTrue(button.performAction(ACTION_FOCUS));
|
||||
|
||||
// find the view again and make sure it is focused
|
||||
button = AccessibilityInteractionClient.getInstance()
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
|
||||
button = mUiTestAutomationBridge
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
|
||||
assertTrue(button.isFocused());
|
||||
|
||||
// unfocus the view
|
||||
assertTrue(button.performAction(ACTION_CLEAR_FOCUS));
|
||||
|
||||
// find the view again and make sure it is not focused
|
||||
button = AccessibilityInteractionClient.getInstance()
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
|
||||
button = mUiTestAutomationBridge
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
|
||||
assertFalse(button.isFocused());
|
||||
} finally {
|
||||
if (DEBUG) {
|
||||
@ -273,16 +282,16 @@ public class InterrogationActivityTest
|
||||
final long startTimeMillis = SystemClock.uptimeMillis();
|
||||
try {
|
||||
// find a view and make sure it is not selected
|
||||
AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
|
||||
AccessibilityNodeInfo button = mUiTestAutomationBridge
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
|
||||
assertFalse(button.isSelected());
|
||||
|
||||
// select the view
|
||||
assertTrue(button.performAction(ACTION_SELECT));
|
||||
|
||||
// find the view again and make sure it is selected
|
||||
button = AccessibilityInteractionClient.getInstance()
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
|
||||
button = mUiTestAutomationBridge
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
|
||||
assertTrue(button.isSelected());
|
||||
} finally {
|
||||
if (DEBUG) {
|
||||
@ -297,24 +306,24 @@ public class InterrogationActivityTest
|
||||
final long startTimeMillis = SystemClock.uptimeMillis();
|
||||
try {
|
||||
// find a view and make sure it is not selected
|
||||
AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
|
||||
AccessibilityNodeInfo button = mUiTestAutomationBridge
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
|
||||
assertFalse(button.isSelected());
|
||||
|
||||
// select the view
|
||||
assertTrue(button.performAction(ACTION_SELECT));
|
||||
|
||||
// find the view again and make sure it is selected
|
||||
button = AccessibilityInteractionClient.getInstance()
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
|
||||
button = mUiTestAutomationBridge
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
|
||||
assertTrue(button.isSelected());
|
||||
|
||||
// unselect the view
|
||||
assertTrue(button.performAction(ACTION_CLEAR_SELECTION));
|
||||
|
||||
// find the view again and make sure it is not selected
|
||||
button = AccessibilityInteractionClient.getInstance()
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
|
||||
button = mUiTestAutomationBridge
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
|
||||
assertFalse(button.isSelected());
|
||||
} finally {
|
||||
if (DEBUG) {
|
||||
@ -330,23 +339,33 @@ public class InterrogationActivityTest
|
||||
final long startTimeMillis = SystemClock.uptimeMillis();
|
||||
try {
|
||||
// find a view and make sure it is not focused
|
||||
AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
|
||||
assertFalse(button.isSelected());
|
||||
final AccessibilityNodeInfo button = mUiTestAutomationBridge
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
|
||||
assertFalse(button.isFocused());
|
||||
|
||||
// focus the view
|
||||
assertTrue(button.performAction(ACTION_FOCUS));
|
||||
|
||||
synchronized (this) {
|
||||
try {
|
||||
wait(TIMEOUT_ACCESSIBLITY_STATE_INITIALIZED_MILLIS);
|
||||
} catch (InterruptedException ie) {
|
||||
/* ignore */
|
||||
AccessibilityEvent event = mUiTestAutomationBridge
|
||||
.executeCommandAndWaitForAccessibilityEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// focus the view
|
||||
assertTrue(button.performAction(ACTION_FOCUS));
|
||||
}
|
||||
}
|
||||
},
|
||||
new Predicate<AccessibilityEvent>() {
|
||||
@Override
|
||||
public boolean apply(AccessibilityEvent event) {
|
||||
return (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED
|
||||
&& event.getPackageName().equals(getActivity().getPackageName())
|
||||
&& event.getText().get(0).equals(button.getText()));
|
||||
}
|
||||
},
|
||||
TIMEOUT_PROPAGATE_ACCESSIBILITY_EVENT_MILLIS);
|
||||
|
||||
// check the last event
|
||||
assertNotNull(event);
|
||||
|
||||
// check that last event source
|
||||
AccessibilityNodeInfo source = mLastAccessibilityEvent.getSource();
|
||||
AccessibilityNodeInfo source = event.getSource();
|
||||
assertNotNull(source);
|
||||
|
||||
// bounds
|
||||
@ -389,8 +408,9 @@ public class InterrogationActivityTest
|
||||
final long startTimeMillis = SystemClock.uptimeMillis();
|
||||
try {
|
||||
// find a view and make sure it is not focused
|
||||
AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
|
||||
AccessibilityNodeInfo button = mUiTestAutomationBridge
|
||||
.findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
|
||||
assertNotNull(button);
|
||||
AccessibilityNodeInfo parent = button.getParent();
|
||||
final int childCount = parent.getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
@ -410,71 +430,4 @@ public class InterrogationActivityTest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void bringUpActivityWithInitalizedAccessbility() {
|
||||
mLastAccessibilityEvent = null;
|
||||
// bring up the activity
|
||||
getActivity();
|
||||
|
||||
final long startTimeMillis = SystemClock.uptimeMillis();
|
||||
while (true) {
|
||||
if (mLastAccessibilityEvent != null) {
|
||||
final int eventType = mLastAccessibilityEvent.getEventType();
|
||||
if (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
final long remainingTimeMillis = TIMEOUT_ACCESSIBLITY_STATE_INITIALIZED_MILLIS
|
||||
- (SystemClock.uptimeMillis() - startTimeMillis);
|
||||
if (remainingTimeMillis <= 0) {
|
||||
return;
|
||||
}
|
||||
synchronized (this) {
|
||||
try {
|
||||
wait(remainingTimeMillis);
|
||||
} catch (InterruptedException e) {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureConnection() throws Exception {
|
||||
if (sConnectionId == View.NO_ID) {
|
||||
IEventListener listener = new IEventListener.Stub() {
|
||||
public void setConnection(IAccessibilityServiceConnection connection,
|
||||
int connectionId) {
|
||||
sConnectionId = connectionId;
|
||||
if (connection != null) {
|
||||
AccessibilityInteractionClient.getInstance().addConnection(connectionId,
|
||||
connection);
|
||||
} else {
|
||||
AccessibilityInteractionClient.getInstance().removeConnection(connectionId);
|
||||
}
|
||||
synchronized (this) {
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void onInterrupt() {}
|
||||
|
||||
public void onAccessibilityEvent(AccessibilityEvent event) {
|
||||
mLastAccessibilityEvent = AccessibilityEvent.obtain(event);
|
||||
synchronized (this) {
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AccessibilityManager accessibilityManager =
|
||||
AccessibilityManager.getInstance(getInstrumentation().getContext());
|
||||
|
||||
synchronized (this) {
|
||||
IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
|
||||
manager.registerEventListener(listener);
|
||||
wait(TIMEOUT_PROPAGATE_ACCESSIBLITY_SETTING);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user