diff --git a/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml b/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml
index 9906227..852a003 100644
--- a/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml
+++ b/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml
@@ -50,7 +50,10 @@
        android:includeFontPadding="false"
        android:textSize="10dip"
        android:textStyle="normal"
+       android:lineSpacingExtra="20dp"
+       android:lineSpacingMultiplier="0.0"
        android:fontFamily="sans-serif"
+       android:background="@null"
        android:visibility="gone"
        />
 
diff --git a/tests/accessibilityservice/res/values/strings.xml b/tests/accessibilityservice/res/values/strings.xml
index 1c34c2c..ff87cb0 100644
--- a/tests/accessibilityservice/res/values/strings.xml
+++ b/tests/accessibilityservice/res/values/strings.xml
@@ -128,9 +128,7 @@
     <string name="android_wiki_short">
         Android is a\nLinux-based\noperating</string>
 
-    <string name="android_wiki">
-        Android is a Linux-based operating system for mobile devices such as smartphones and tablet
-        computers. It is developed by the Open Handset Alliance, more</string>
+    <string name="android_wiki">Android is a Linux-based operating system for mobile devices such as smartphones and tablet computers. It is developed by the Open Handset Alliance, and here is some text padding</string>
 
     <string name="a_b">A B</string>
 
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
index d8a1be1..9dd40fe 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
@@ -55,6 +55,10 @@
         super(AccessibilityEndToEndActivity.class);
     }
 
+    public void tearDown() {
+        getInstrumentation().getUiAutomation().destroy();
+    }
+
     @MediumTest
     public void testTypeViewSelectedAccessibilityEvent() throws Throwable {
         // create and populate the expected event
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncTest.java
index ec420de..892fbb0 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncTest.java
@@ -40,6 +40,10 @@
         super(AccessibilityFocusAndInputFocusSyncActivity.class);
     }
 
+    public void tearDown() {
+        getInstrumentation().getUiAutomation().destroy();
+    }
+
     @MediumTest
     public void testFindAccessibilityFocus() throws Exception {
         // Get the view that has input and accessibility focus.
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
index f5958f9..69acfcd 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
@@ -33,12 +33,19 @@
  * a View at several granularities.
  */
 public class AccessibilityTextTraversalTest
-        extends AccessibilityActivityTestCase<AccessibilityTextTraversalActivity>{
+        extends AccessibilityActivityTestCase<AccessibilityTextTraversalActivity> {
+    // The number of characters per page may vary with font, so this number is slightly uncertain.
+    // We need some threshold, however, to make sure moving by a page isn't just moving by a line.
+    private static final int[] CHARACTER_INDICES_OF_PAGE_START = {0, 53, 122, 178};
 
     public AccessibilityTextTraversalTest() {
         super(AccessibilityTextTraversalActivity.class);
     }
 
+    public void tearDown() {
+        getInstrumentation().getUiAutomation().destroy();
+    }
+
     @MediumTest
     public void testActionNextAndPreviousAtGranularityCharacterOverContentDescription()
             throws Exception {
@@ -2994,231 +3001,55 @@
         arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
 
-        // Move to the next page and wait for an event.
-        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 53
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
+        // Move forward a few pages
+        for (int i = 0; i < CHARACTER_INDICES_OF_PAGE_START.length - 1; i++) {
+            AccessibilityEvent event = performMovementActionAndGetEvent(
+                    text,
+                    AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
+                    AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE,
+                    false);
+            assertEquals(event.getClassName(), EditText.class.getName());
+            assertTrue("Event should contain text", event.getText().size() > 0);
+            assertTrue("Event text doesn't match. Expected: " + getString(R.string.android_wiki)
+                    + ". Received:" + event.getText().get(0),
+                    TextUtils.equals(event.getText().get(0), getString(R.string.android_wiki)));
+            assertEquals("Event from should be start of text skipped.",
+                    CHARACTER_INDICES_OF_PAGE_START[i], event.getFromIndex());
+            assertEquals("Event to should be end of text skipped.",
+                    CHARACTER_INDICES_OF_PAGE_START[i + 1], event.getToIndex());
+            // Verify the selection position has changed.
+            assertEquals("Event selection start should match position it moved to.",
+                    CHARACTER_INDICES_OF_PAGE_START[i + 1],
+                    Selection.getSelectionStart(editText.getText()));
+            assertEquals("Event selection end should match position it moved to.",
+                    CHARACTER_INDICES_OF_PAGE_START[i + 1],
+                    Selection.getSelectionEnd(editText.getText()));
+        }
 
-        // Make sure we got the expected event.
-        assertNotNull(firstExpected);
-
-        // Verify the selection position.
-        assertEquals(53, Selection.getSelectionStart(editText.getText()));
-        assertEquals(53, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next page and wait for an event.
-        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 53
-                        && event.getToIndex() == 103
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(secondExpected);
-
-        // Verify the selection position.
-        assertEquals(103, Selection.getSelectionStart(editText.getText()));
-        assertEquals(103, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next page and wait for an event.
-        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 103
-                        && event.getToIndex() == 153
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(thirdExpected);
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(153, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no next.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(153, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 103
-                        && event.getToIndex() == 153
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fourthExpected);
-
-        // Verify the selection position.
-        assertEquals(103, Selection.getSelectionStart(editText.getText()));
-        assertEquals(103, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 53
-                        && event.getToIndex() == 103
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fifthExpected);
-
-        // Verify the selection position.
-        assertEquals(53, Selection.getSelectionStart(editText.getText()));
-        assertEquals(53, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 53
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(sixthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
+        // Move back to the beginning
+        for (int i = CHARACTER_INDICES_OF_PAGE_START.length - 2; i >= 0; i--) {
+            AccessibilityEvent event = performMovementActionAndGetEvent(
+                    text,
+                    AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
+                    AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE,
+                    false);
+            assertEquals(event.getClassName(), EditText.class.getName());
+            assertTrue("Event should contain text", event.getText().size() > 0);
+            assertTrue("Event text doesn't match. Expected: " + getString(R.string.android_wiki)
+                            + ". Received:" + event.getText().get(0),
+                    TextUtils.equals(event.getText().get(0), getString(R.string.android_wiki)));
+            assertEquals("Event from should be start of text skipped.",
+                    CHARACTER_INDICES_OF_PAGE_START[i], event.getFromIndex());
+            assertEquals("Event to should be end of text skipped.",
+                    CHARACTER_INDICES_OF_PAGE_START[i + 1], event.getToIndex());
+            // Verify the selection position has changed.
+            assertEquals("Event selection start should match position it moved to.",
+                    CHARACTER_INDICES_OF_PAGE_START[i],
+                    Selection.getSelectionStart(editText.getText()));
+            assertEquals("Event selection end should match position it moved to.",
+                    CHARACTER_INDICES_OF_PAGE_START[i],
+                    Selection.getSelectionEnd(editText.getText()));
+        }
     }
 
     @MediumTest
@@ -3248,476 +3079,54 @@
         final Bundle arguments = new Bundle();
         arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
                 AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-        arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true);
 
-        // Move to the next page and wait for an event.
-        AccessibilityEvent firstExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 53
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
+        // Move forward a few pages
+        for (int i = 0; i < CHARACTER_INDICES_OF_PAGE_START.length - 1; i++) {
+            AccessibilityEvent event = performMovementActionAndGetEvent(
+                    text,
+                    AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
+                    AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE,
+                    true);
+            assertEquals(event.getClassName(), EditText.class.getName());
+            assertTrue("Event should contain text", event.getText().size() > 0);
+            assertTrue("Event text doesn't match. Expected: " + getString(R.string.android_wiki)
+                            + ". Received:" + event.getText().get(0),
+                    TextUtils.equals(event.getText().get(0), getString(R.string.android_wiki)));
+            assertEquals("Event from should be start of text skipped",
+                    CHARACTER_INDICES_OF_PAGE_START[i], event.getFromIndex());
+            assertEquals("Event to should be end of text skipped",
+                    CHARACTER_INDICES_OF_PAGE_START[i + 1], event.getToIndex());
+            // Verify the selection position has changed.
+            assertEquals("Event selection start should stay at beginning",
+                    0, Selection.getSelectionStart(editText.getText()));
+            assertEquals("Event selection end should match current position",
+                    CHARACTER_INDICES_OF_PAGE_START[i + 1],
+                    Selection.getSelectionEnd(editText.getText()));
+        }
 
-        // Make sure we got the expected event.
-        assertNotNull(firstExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(53, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next page and wait for an event.
-        AccessibilityEvent secondExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 53
-                        && event.getToIndex() == 103
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(secondExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(103, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next page and wait for an event.
-        AccessibilityEvent thirdExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 103
-                        && event.getToIndex() == 153
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(thirdExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(153, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no next.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent fourthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                 AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 103
-                        && event.getToIndex() == 153
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fourthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(103, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent fifthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 53
-                        && event.getToIndex() == 103
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(fifthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(53, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent sixthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 53
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(sixthExpected);
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(0, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Focus the view so we can change selection.
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.setFocusable(true);
-                editText.requestFocus();
-            }
-        });
-
-        // Put selection at the end of the text.
-        Bundle setSelectionArgs = new Bundle();
-        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 153);
-        setSelectionArgs.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 153);
-        assertTrue(text.performAction(
-                AccessibilityNodeInfo.ACTION_SET_SELECTION, setSelectionArgs));
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(153, Selection.getSelectionEnd(editText.getText()));
-
-        // Unfocus the view so we can hide the soft-keyboard.
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.clearFocus();
-                editText.setFocusable(false);
-            }
-        });
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent seventhExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                 AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 103
-                        && event.getToIndex() == 153
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(seventhExpected);
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(103, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent eightExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 53
-                        && event.getToIndex() == 103
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(eightExpected);
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(53, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the previous page and wait for an event.
-        AccessibilityEvent ninethExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 53
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(ninethExpected);
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Make sure there is no previous.
-        assertFalse(text.performAction(
-                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(0, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next page and wait for an event.
-        AccessibilityEvent tenthExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 0
-                        && event.getToIndex() == 53
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(tenthExpected);
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(53, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next page and wait for an event.
-        AccessibilityEvent eleventhExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 53
-                        && event.getToIndex() == 103
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(eleventhExpected);
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(103, Selection.getSelectionEnd(editText.getText()));
-
-        // Move to the next page and wait for an event.
-        AccessibilityEvent twelvethExpected = getInstrumentation().getUiAutomation()
-                .executeAndWaitForEvent(new Runnable() {
-            @Override
-            public void run() {
-                text.performAction(
-                        AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
-            }
-        }, new UiAutomation.AccessibilityEventFilter() {
-            @Override
-            public boolean accept(AccessibilityEvent event) {
-                return
-                (event.getEventType() ==
-                    AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
-                        && event.getAction() ==
-                                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
-                        && event.getPackageName().equals(getActivity().getPackageName())
-                        && event.getClassName().equals(EditText.class.getName())
-                        && event.getText().size() > 0
-                        && event.getText().get(0).toString().equals(getString(
-                                R.string.android_wiki))
-                        && event.getFromIndex() == 103
-                        && event.getToIndex() == 153
-                        && event.getMovementGranularity() ==
-                                AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
-            }
-        }, TIMEOUT_ASYNC_PROCESSING);
-
-        // Make sure we got the expected event.
-        assertNotNull(twelvethExpected);
-
-        // Verify the selection position.
-        assertEquals(153, Selection.getSelectionStart(editText.getText()));
-        assertEquals(153, Selection.getSelectionEnd(editText.getText()));
+        // Move back to the beginning
+        for (int i = CHARACTER_INDICES_OF_PAGE_START.length - 2; i >= 0; i--) {
+            AccessibilityEvent event = performMovementActionAndGetEvent(
+                    text,
+                    AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
+                    AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE,
+                    true);
+            assertEquals(event.getClassName(), EditText.class.getName());
+            assertTrue("Event should contain text", event.getText().size() > 0);
+            assertTrue("Event text doesn't match. Expected: " + getString(R.string.android_wiki)
+                            + ". Received:" + event.getText().get(0),
+                    TextUtils.equals(event.getText().get(0), getString(R.string.android_wiki)));
+            assertEquals("Event from should be start of text skipped",
+                    CHARACTER_INDICES_OF_PAGE_START[i], event.getFromIndex());
+            assertEquals("Event to should be end of text skipped",
+                    CHARACTER_INDICES_OF_PAGE_START[i + 1], event.getToIndex());
+            // Verify the selection position has changed.
+            assertEquals("Event selection start should stay at beginning",
+                    0, Selection.getSelectionStart(editText.getText()));
+            assertEquals("Event selection end should match current position",
+                    CHARACTER_INDICES_OF_PAGE_START[i],
+                    Selection.getSelectionEnd(editText.getText()));
+        }
     }
 
     @MediumTest
@@ -4643,4 +4052,36 @@
         assertSame(refreshedText.getTextSelectionStart(), 4);
         assertSame(refreshedText.getTextSelectionEnd(), 4);
     }
+
+    private AccessibilityEvent performMovementActionAndGetEvent(final AccessibilityNodeInfo target,
+            final int action, final int granularity, final boolean extendSelection)
+            throws Exception {
+        final Bundle arguments = new Bundle();
+        arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
+                granularity);
+        if (extendSelection) {
+            arguments.putBoolean(
+                    AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, true);
+        }
+        Runnable performActionRunnable = new Runnable() {
+            @Override
+            public void run() {
+                target.performAction(action, arguments);
+            }
+        };
+        UiAutomation.AccessibilityEventFilter filter = new UiAutomation.AccessibilityEventFilter() {
+            @Override
+            public boolean accept(AccessibilityEvent event) {
+                boolean isMovementEvent = event.getEventType()
+                        == AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY;
+                boolean actionMatches = event.getAction() == action;
+                boolean packageMatches =
+                        event.getPackageName().equals(getActivity().getPackageName());
+                boolean granularityMatches = event.getMovementGranularity() == granularity;
+                return isMovementEvent && actionMatches && packageMatches && granularityMatches;
+            }
+        };
+        return getInstrumentation().getUiAutomation()
+                .executeAndWaitForEvent(performActionRunnable, filter, TIMEOUT_ASYNC_PROCESSING);
+    }
 }
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java
index a292e4e..b04e98b 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java
@@ -39,6 +39,10 @@
         super(AccessibilityViewTreeReportingActivity.class);
     }
 
+    public void tearDown() {
+        getInstrumentation().getUiAutomation().destroy();
+    }
+
     @MediumTest
     public void testDescendantsOfNotImportantViewReportedInOrder1() throws Exception {
         UiAutomation uiAutomation = getUiAutomation(false);
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
index d328916..12c251b 100755
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
@@ -60,6 +60,10 @@
         super(AccessibilityWindowQueryActivity.class);
     }
 
+    public void tearDown() {
+        getInstrumentation().getUiAutomation().destroy();
+    }
+
     @MediumTest
     public void testFindByText() throws Exception {
         // find a view by text
