diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/webkit/AccessibilityInjector.java | 11 | ||||
-rw-r--r-- | core/java/android/webkit/WebView.java | 35 | ||||
-rw-r--r-- | core/java/android/webkit/WebViewCore.java | 29 | ||||
-rw-r--r-- | core/tests/coretests/src/android/webkit/AccessibilityInjectorTest.java | 570 |
4 files changed, 592 insertions, 53 deletions
diff --git a/core/java/android/webkit/AccessibilityInjector.java b/core/java/android/webkit/AccessibilityInjector.java index 6bb4320..db66305 100644 --- a/core/java/android/webkit/AccessibilityInjector.java +++ b/core/java/android/webkit/AccessibilityInjector.java @@ -113,6 +113,11 @@ class AccessibilityInjector { * @return True if the event was processed. */ public boolean onKeyEvent(KeyEvent event) { + // We do not handle ENTER in any circumstances. + if (isEnterActionKey(event.getKeyCode())) { + return false; + } + if (event.getAction() == KeyEvent.ACTION_UP) { return mLastDownEventHandled; } @@ -367,6 +372,12 @@ class AccessibilityInjector { } } + private boolean isEnterActionKey(int keyCode) { + return keyCode == KeyEvent.KEYCODE_DPAD_CENTER + || keyCode == KeyEvent.KEYCODE_ENTER + || keyCode == KeyEvent.KEYCODE_NUMPAD_ENTER; + } + /** * Represents a web content key-binding. */ diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index cf1ce6b..9bd57cd 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -16,9 +16,6 @@ package android.webkit; -import android.view.HardwareCanvas; -import com.android.internal.R; - import android.annotation.Widget; import android.app.AlertDialog; import android.content.BroadcastReceiver; @@ -31,7 +28,6 @@ import android.content.IntentFilter; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; -import android.content.res.Resources; import android.database.DataSetObserver; import android.graphics.Bitmap; import android.graphics.BitmapFactory; @@ -57,7 +53,6 @@ import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.Message; -import android.os.SystemClock; import android.provider.Settings; import android.speech.tts.TextToSpeech; import android.text.Selection; @@ -66,6 +61,7 @@ import android.util.AttributeSet; import android.util.EventLog; import android.util.Log; import android.view.Gravity; +import android.view.HardwareCanvas; import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -92,7 +88,6 @@ import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.CheckedTextView; -import android.widget.EdgeGlow; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.OverScroller; @@ -677,6 +672,8 @@ public class WebView extends AbsoluteLayout static final int SET_AUTOFILLABLE = 133; static final int AUTOFILL_COMPLETE = 134; + static final int SELECT_AT = 135; + private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID; private static final int LAST_PACKAGE_MSG_ID = SET_TOUCH_HIGHLIGHT_RECTS; @@ -728,7 +725,8 @@ public class WebView extends AbsoluteLayout "SET_TOUCH_HIGHLIGHT_RECTS", // = 131; "SAVE_WEBARCHIVE_FINISHED", // = 132; "SET_AUTOFILLABLE", // = 133; - "AUTOFILL_COMPLETE" // = 134; + "AUTOFILL_COMPLETE", // = 134; + "SELECT_AT" // = 135; }; // If the site doesn't use the viewport meta tag to specify the viewport, @@ -7600,6 +7598,10 @@ public class WebView extends AbsoluteLayout } break; + case SELECT_AT: + nativeSelectAt(msg.arg1, msg.arg2); + break; + default: super.handleMessage(msg); break; @@ -7957,24 +7959,6 @@ public class WebView extends AbsoluteLayout cursorData()); } - /* - * Called from JNI when the cursor has moved. This method - * sends a message to the WebCore requesting the given - * nodePtr in the given framePrt to be selected which will - * result in firing an accessibility event announing its - * content. - * - * Note: Accessibility support. - */ - @SuppressWarnings("unused") - // called from JNI - private void sendMoveSelection(int framePtr, int nodePtr) { - if (AccessibilityManager.getInstance(mContext).isEnabled() - && mAccessibilityInjector != null) { - mWebViewCore.sendMessage(EventHub.MOVE_SELECTION, framePtr, nodePtr); - } - } - /** * Called by JNI to send a message to the webcore thread that the user * touched the webpage. @@ -8283,6 +8267,7 @@ public class WebView extends AbsoluteLayout private native Point nativeSelectableText(); private native void nativeSelectAll(); private native void nativeSelectBestAt(Rect rect); + private native void nativeSelectAt(int x, int y); private native int nativeSelectionX(); private native int nativeSelectionY(); private native int nativeFindIndex(); diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 0992079..0451a13 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -641,18 +641,6 @@ final class WebViewCore { */ private native String nativeModifySelection(int direction, int granularity); - /** - * Moves the selection to given node i.e. selects that node. - * - * Note: Accessibility support. - * - * @param framePtr Pointer to the frame containing the node to be selected. - * @param nodePtr Pointer to the node to be selected. - * - * @return The selection string. - */ - private native String nativeMoveSelection(int framePtr, int nodePtr); - // EventHub for processing messages private final EventHub mEventHub; // WebCore thread handler @@ -1018,9 +1006,6 @@ final class WebViewCore { static final int PROXY_CHANGED = 193; - // accessibility support - static final int MOVE_SELECTION = 194; - // private message ids private static final int DESTROY = 200; @@ -1439,12 +1424,6 @@ final class WebViewCore { modifiedSelectionString).sendToTarget(); break; - case MOVE_SELECTION: - String movedSelectionString = nativeMoveSelection(msg.arg1, msg.arg2); - mWebView.mPrivateHandler.obtainMessage(WebView.SELECTION_STRING_CHANGED, - movedSelectionString).sendToTarget(); - break; - case LISTBOX_CHOICES: SparseBooleanArray choices = (SparseBooleanArray) msg.obj; @@ -2714,6 +2693,14 @@ final class WebViewCore { hMode, vMode).sendToTarget(); } + // called by JNI + @SuppressWarnings("unused") + private void selectAt(int x, int y) { + if (mWebView != null) { + mWebView.mPrivateHandler.obtainMessage(WebView.SELECT_AT, x, y).sendToTarget(); + } + } + private void useMockDeviceOrientation() { mDeviceMotionAndOrientationManager.useMock(); } diff --git a/core/tests/coretests/src/android/webkit/AccessibilityInjectorTest.java b/core/tests/coretests/src/android/webkit/AccessibilityInjectorTest.java index 4edd127..16108e6 100644 --- a/core/tests/coretests/src/android/webkit/AccessibilityInjectorTest.java +++ b/core/tests/coretests/src/android/webkit/AccessibilityInjectorTest.java @@ -51,7 +51,7 @@ public class AccessibilityInjectorTest extends AndroidTestCase { private static final long TIMEOUT_ENABLE_ACCESSIBILITY_AND_MOCK_SERVICE = 1000; /** The count of tests to detect when to shut down the service. */ - private static final int TEST_CASE_COUNT = 8; + private static final int TEST_CASE_COUNT = 16; /** The meta state for pressed left ALT. */ private static final int META_STATE_ALT_LEFT_ON = KeyEvent.META_ALT_ON @@ -140,7 +140,8 @@ public class AccessibilityInjectorTest extends AndroidTestCase { "</p>" + "<p>" + "d" + - "<input>e</input>" + + "<p/>" + + "e" + "</p>" + "</body>" + "</html>"; @@ -179,6 +180,10 @@ public class AccessibilityInjectorTest extends AndroidTestCase { sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); assertSelectionString(null); + // go to the fifth character (reverse) + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("e"); + // go to the fourth character (reverse) sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); assertSelectionString("d"); @@ -199,6 +204,10 @@ public class AccessibilityInjectorTest extends AndroidTestCase { sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); assertSelectionString(null); + // go to the first character + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("a"); + // go to the second character (reverse again) sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); assertSelectionString("<b>b</b>"); @@ -223,11 +232,11 @@ public class AccessibilityInjectorTest extends AndroidTestCase { "</p>" + "<p>" + " scattered " + - "<input>all</input>" + - " over " + + "<p/>" + + " all over " + "</p>" + "<div>" + - "<button>the place.</button>" + + "<p>the place.</p>" + "</div>" + "</body>" + "</html>"; @@ -284,7 +293,7 @@ public class AccessibilityInjectorTest extends AndroidTestCase { // go to the last word (reverse) sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); - assertSelectionString("place"); + assertSelectionString("place."); // go to the eight word sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); @@ -322,6 +331,10 @@ public class AccessibilityInjectorTest extends AndroidTestCase { sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); assertSelectionString(null); + // go to the first word + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("This"); + // go to the second word (reverse again) sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); assertSelectionString("is"); @@ -384,6 +397,10 @@ public class AccessibilityInjectorTest extends AndroidTestCase { sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); assertSelectionString(null); + // go to the fifth sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("This is the second sentence of the second paragraph."); + // go to the fourth sentence (reverse) sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); assertSelectionString("This is the first sentence of the second paragraph."); @@ -405,6 +422,11 @@ public class AccessibilityInjectorTest extends AndroidTestCase { sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); assertSelectionString(null); + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("This is the first sentence of the first paragraph and has an " + + "<b>inline bold tag</b>."); + // go to the second sentence (reverse again) sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); assertSelectionString("This is the second sentence of the first paragraph."); @@ -747,6 +769,539 @@ public class AccessibilityInjectorTest extends AndroidTestCase { } /** + * Tests that the selection does not cross anchor boundaries. This is a + * workaround for the asymmetric and inconsistent handling of text with + * links by WebKit while traversing by sentence. + */ + @LargeTest + public void testEnforceSelectionDoesNotCrossAnchorBoundary1() throws Exception { + // a bit ugly but helps detect beginning and end of all tests so accessibility + // and the mock service are not toggled on every test (expensive) + sExecutedTestCount++; + + String html = + "<!DOCTYPE html>" + + "<html>" + + "<head>" + + "</head>" + + "<body>" + + "<div>First</div>" + + "<p>" + + "<a href=\"\">Second</a> Third" + + "</p>" + + "</body>" + + "</html>"; + + WebView webView = createWebVewWithHtml(html); + + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("First"); + + // go to the second sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("<a href=\"\">Second</a>"); + + // go to the third sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("Third"); + + // go to past the last sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString(null); + + // go to the third sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("Third"); + + // go to the second sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("<a href=\"\">Second</a>"); + + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("First"); + + // go to before the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString(null); + + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("First"); + } + + /** + * Tests that the selection does not cross anchor boundaries. This is a + * workaround for the asymmetric and inconsistent handling of text with + * links by WebKit while traversing by sentence. + */ + @LargeTest + public void testEnforceSelectionDoesNotCrossAnchorBoundary2() throws Exception { + // a bit ugly but helps detect beginning and end of all tests so accessibility + // and the mock service are not toggled on every test (expensive) + sExecutedTestCount++; + + String html = + "<!DOCTYPE html>" + + "<html>" + + "<head>" + + "</head>" + + "<body>" + + "<div>First</div>" + + "<a href=\"#\">Second</a>" + + " " + + "<a href=\"#\">Third</a>" + + "</body>" + + "</html>"; + + WebView webView = createWebVewWithHtml(html); + + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("First"); + + // go to the second sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("<a href=\"#\">Second</a>"); + + // go to the third sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString(" "); + + // go to the fourth sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("<a href=\"#\">Third</a>"); + + // go to past the last sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString(null); + + // go to the fourth sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("<a href=\"#\">Third</a>"); + + // go to the third sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString(" "); + + // go to the second sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("<a href=\"#\">Second</a>"); + + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("First"); + + // go to before the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString(null); + + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("First"); + } + + /** + * Tests that the selection does not cross anchor boundaries. This is a + * workaround for the asymmetric and inconsistent handling of text with + * links by WebKit while traversing by sentence. + */ + @LargeTest + public void testEnforceSelectionDoesNotCrossAnchorBoundary3() throws Exception { + // a bit ugly but helps detect beginning and end of all tests so accessibility + // and the mock service are not toggled on every test (expensive) + sExecutedTestCount++; + + String html = + "<!DOCTYPE html>" + + "<html>" + + "<head>" + + "</head>" + + "<body>" + + "<div>" + + "First" + + "<div>" + + "<div>" + + "<a href=\"#\">Second</a>" + + "</div>" + + "<div>" + + "Third" + + "</div>" + + "</body>" + + "</html>"; + + WebView webView = createWebVewWithHtml(html); + + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("First"); + + // go to the second sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("<a href=\"#\">Second</a>"); + + // go to the third sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("Third"); + + // go to past the last sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString(null); + + // go to the third sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("Third"); + + // go to the second sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("<a href=\"#\">Second</a>"); + + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("First"); + + // go to before the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString(null); + + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("First"); + } + + /** + * Tests skipping of content with hidden visibility. + */ + @LargeTest + public void testSkipVisibilityHidden() throws Exception { + // a bit ugly but helps detect beginning and end of all tests so accessibility + // and the mock service are not toggled on every test (expensive) + sExecutedTestCount++; + + String html = + "<!DOCTYPE html>" + + "<html>" + + "<head>" + + "</head>" + + "<body>" + + "<div>First </div>" + + "<div style=\"visibility:hidden;\">Second</div>" + + "<div> Third</div>" + + "</body>" + + "</html>"; + + WebView webView = createWebVewWithHtml(html); + + // change navigation axis to word + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, META_STATE_ALT_LEFT_ON); + assertSelectionString("1"); // expect the word navigation axis + + // go to the first word + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("First"); + + // go to the third word (the second is invisible) + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("Third"); + + // go to past the last sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString(null); + + // go to the third word (the second is invisible) + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("Third"); + + // go to the first word + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("First"); + + // go to before the first word + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString(null); + + // go to the first word + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("First"); + } + + /** + * Tests skipping of content with display none. + */ + @LargeTest + public void testSkipDisplayNone() throws Exception { + // a bit ugly but helps detect beginning and end of all tests so accessibility + // and the mock service are not toggled on every test (expensive) + sExecutedTestCount++; + + String html = + "<!DOCTYPE html>" + + "<html>" + + "<head>" + + "</head>" + + "<body>" + + "<div>First</div>" + + "<div style=\"display: none;\">Second</div>" + + "<div>Third</div>" + + "</body>" + + "</html>"; + + WebView webView = createWebVewWithHtml(html); + + // change navigation axis to word + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, META_STATE_ALT_LEFT_ON); + assertSelectionString("1"); // expect the word navigation axis + + // go to the first word + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("First"); + + // go to the third word (the second is invisible) + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("Third"); + + // go to past the last sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString(null); + + // go to the third word (the second is invisible) + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("Third"); + + // go to the first word + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("First"); + + // go to before the first word + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString(null); + + // go to the first word + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("First"); + } + + /** + * Tests for the selection not getting stuck. + * + * Note: The selection always proceeds but if it can + * be selecting the same content i.e. between the start + * and end are contained the same text nodes. + */ + @LargeTest + public void testSelectionTextProceed() throws Exception { + // a bit ugly but helps detect beginning and end of all tests so accessibility + // and the mock service are not toggled on every test (expensive) + sExecutedTestCount++; + + String html = + "<!DOCTYPE html>" + + "<html>" + + "<head>" + + "</head>" + + "<body>" + + "<a href=\"#\">First</a>" + + "<span><a href=\"#\"><span>Second</span> <small>a</small></a>" + + "</span> <a href=\"#\">Third</a>" + + "</body>" + + "</html>"; + + WebView webView = createWebVewWithHtml(html); + + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("<a href=\"#\">First</a>"); + + // go to the second sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("<a href=\"#\"><span>Second <small>a</small></a>"); + + // go to the third sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString(" "); + + // go to the fourth sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("<a href=\"#\">Third</a>"); + + // go to past the last sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString(null); + + // go to the third sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("<a href=\"#\">Third</a>"); + + // NOTE: Here we are a bit asymmetric around whitespace but we can live with it + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString(" "); + + // go to the second sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("<a href=\"#\"><span>Second <small>a</small></a>"); + + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("<a href=\"#\">First</a>"); + + // go to before the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString(null); + + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("<a href=\"#\">First</a>"); + } + + /** + * Tests if input elements are selected rather skipped. + */ + @LargeTest + public void testSelectionOfInputElements() throws Exception { + // a bit ugly but helps detect beginning and end of all tests so accessibility + // and the mock service are not toggled on every test (expensive) + sExecutedTestCount++; + + String html = + "<!DOCTYPE html>" + + "<html>" + + "<head>" + + "</head>" + + "<body>" + + "<p>" + + "First" + + "</p>" + + "<input type=\"text\"/>" + + "<p>" + + "Second" + + "</p>" + + "</body>" + + "</html>"; + + WebView webView = createWebVewWithHtml(html); + + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("First"); + + // go to the second sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("<input type=\"text\">"); + + // go to the third sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("Second"); + + // go to past the last sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString(null); + + // go to the third sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("Second"); + + // go to the second sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("<input type=\"text\">"); + + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("First"); + + // go to before the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString(null); + + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("First"); + } + + /** + * Tests traversing of input controls. + */ + @LargeTest + public void testSelectionOfInputElements2() throws Exception { + // a bit ugly but helps detect beginning and end of all tests so accessibility + // and the mock service are not toggled on every test (expensive) + sExecutedTestCount++; + + String html = + "<!DOCTYPE html>" + + "<html>" + + "<head>" + + "</head>" + + "<body>" + + "<div>" + + "First" + + "<input type=\"text\"/>" + + "<span>" + + "<input type=\"text\"/>" + + "</span>" + + "<button type=\"button\">Click Me!</button>" + + "<div>" + + "<input type=\"submit\"/>" + + "</div>" + + "<p>" + + "Second" + + "</p>" + + "</div>" + + "</body>" + + "</html>"; + + WebView webView = createWebVewWithHtml(html); + + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("First"); + + // go to the second sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("<input type=\"text\">"); + + // go to the third sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("<input type=\"text\">"); + + // go to the fourth sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("<button type=\"button\">Click Me!</button>"); + + // go to the fifth sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("<input type=\"submit\">"); + + // go to the sixth sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString("Second"); + + // go to past the last sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0); + assertSelectionString(null); + + // go to the sixth sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("Second"); + + // go to the fifth sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("<input type=\"submit\">"); + + // go to the fourth sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("<button type=\"button\">Click Me!</button>"); + + // go to the third sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("<input type=\"text\">"); + + // go to the first sentence + sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0); + assertSelectionString("First"); + } + + /** * Enable accessibility and the mock accessibility service. */ private void enableAccessibilityAndMockAccessibilityService() { @@ -887,7 +1442,8 @@ public class AccessibilityInjectorTest extends AndroidTestCase { */ private void restoreDefaultWebContentKeyBindings() { Settings.Secure.putString(getContext().getContentResolver(), - Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS, mDefaultKeyBindings); + Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS, + mDefaultKeyBindings); } /** |