diff options
author | Charles Chen <clchen@google.com> | 2012-10-12 13:46:08 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-10-12 13:46:09 -0700 |
commit | 4c38e24afb0fe68d6e9f6e924e6426808be2611a (patch) | |
tree | e58b7690c87227ac2e866fd90163a4e94a7dbdd0 /core/java | |
parent | c378656d5e0e686d806661bc271de3c7b1726430 (diff) | |
parent | 03e636f33dfdb2f9438f06997a52b43291a83e41 (diff) | |
download | frameworks_base-4c38e24afb0fe68d6e9f6e924e6426808be2611a.zip frameworks_base-4c38e24afb0fe68d6e9f6e924e6426808be2611a.tar.gz frameworks_base-4c38e24afb0fe68d6e9f6e924e6426808be2611a.tar.bz2 |
Merge "Don't alter accessibility JS APIs unless a page is about to load." into jb-mr1-dev
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/webkit/AccessibilityInjector.java | 127 | ||||
-rw-r--r-- | core/java/android/webkit/WebViewClassic.java | 14 |
2 files changed, 96 insertions, 45 deletions
diff --git a/core/java/android/webkit/AccessibilityInjector.java b/core/java/android/webkit/AccessibilityInjector.java index 357a16e..fe5cad4 100644 --- a/core/java/android/webkit/AccessibilityInjector.java +++ b/core/java/android/webkit/AccessibilityInjector.java @@ -97,9 +97,12 @@ class AccessibilityInjector { // Template for JavaScript that performs AndroidVox actions. private static final String ACCESSIBILITY_ANDROIDVOX_TEMPLATE = "(function() {" + - " if ((typeof(cvox) != 'undefined')"+ + " if ((typeof(cvox) != 'undefined')" + + " && (cvox != null)" + " && (typeof(cvox.ChromeVox) != 'undefined')" + + " && (cvox.ChromeVox != null)" + " && (typeof(cvox.AndroidVox) != 'undefined')" + + " && (cvox.AndroidVox != null)" + " && cvox.ChromeVox.isActive) {" + " return cvox.AndroidVox.performAction('%1s');" + " } else {" + @@ -110,9 +113,12 @@ class AccessibilityInjector { // JS code used to shut down an active AndroidVox instance. private static final String TOGGLE_CVOX_TEMPLATE = "javascript:(function() {" + - " if ((typeof(cvox) != 'undefined')"+ + " if ((typeof(cvox) != 'undefined')" + + " && (cvox != null)" + " && (typeof(cvox.ChromeVox) != 'undefined')" + - " && (typeof(cvox.ChromeVox.host) != 'undefined')) {" + + " && (cvox.ChromeVox != null)" + + " && (typeof(cvox.ChromeVox.host) != 'undefined')" + + " && (cvox.ChromeVox.host != null)) {" + " cvox.ChromeVox.host.activateOrDeactivateChromeVox(%b);" + " }" + "})();"; @@ -132,33 +138,60 @@ class AccessibilityInjector { } /** + * If JavaScript is enabled, pauses or resumes AndroidVox. + * + * @param enabled Whether feedback should be enabled. + */ + public void toggleAccessibilityFeedback(boolean enabled) { + if (!isAccessibilityEnabled() || !isJavaScriptEnabled()) { + return; + } + + toggleAndroidVox(enabled); + + if (!enabled && (mTextToSpeech != null)) { + mTextToSpeech.stop(); + } + } + + /** * Attempts to load scripting interfaces for accessibility. * <p> - * This should be called when the window is attached. - * </p> + * This should only be called before a page loads. */ - public void addAccessibilityApisIfNecessary() { + private void addAccessibilityApisIfNecessary() { if (!isAccessibilityEnabled() || !isJavaScriptEnabled()) { return; } addTtsApis(); addCallbackApis(); - toggleAndroidVox(true); } /** * Attempts to unload scripting interfaces for accessibility. * <p> - * This should be called when the window is detached. - * </p> + * This should only be called before a page loads. */ - public void removeAccessibilityApisIfNecessary() { - toggleAndroidVox(false); + private void removeAccessibilityApisIfNecessary() { removeTtsApis(); removeCallbackApis(); } + /** + * Destroys this accessibility injector. + */ + public void destroy() { + if (mTextToSpeech != null) { + mTextToSpeech.shutdown(); + mTextToSpeech = null; + } + + if (mCallback != null) { + mCallback = null; + } + } + private void toggleAndroidVox(boolean state) { if (!mAccessibilityScriptInjected) { return; @@ -517,7 +550,12 @@ class AccessibilityInjector { * settings. */ private boolean isJavaScriptEnabled() { - return mWebView.getSettings().getJavaScriptEnabled(); + final WebSettings settings = mWebView.getSettings(); + if (settings == null) { + return false; + } + + return settings.getJavaScriptEnabled(); } /** @@ -732,7 +770,7 @@ class AccessibilityInjector { private final String mInterfaceName; private boolean mResult = false; - private long mResultId = -1; + private int mResultId = -1; private CallbackHandler(String interfaceName) { mInterfaceName = interfaceName; @@ -784,34 +822,46 @@ class AccessibilityInjector { * @return Whether the result was received. */ private boolean waitForResultTimedLocked(int resultId) { - if (DEBUG) - Log.d(TAG, "Waiting for CVOX result..."); - long waitTimeMillis = RESULT_TIMEOUT; final long startTimeMillis = SystemClock.uptimeMillis(); + + if (DEBUG) + Log.d(TAG, "Waiting for CVOX result with ID " + resultId + "..."); + while (true) { + // Fail if we received a callback from the future. + if (mResultId > resultId) { + if (DEBUG) + Log.w(TAG, "Aborted CVOX result"); + return false; + } + + final long elapsedTimeMillis = (SystemClock.uptimeMillis() - startTimeMillis); + + // Succeed if we received the callback we were expecting. + if (DEBUG) + Log.w(TAG, "Check " + mResultId + " versus expected " + resultId); + if (mResultId == resultId) { + if (DEBUG) + Log.w(TAG, "Received CVOX result after " + elapsedTimeMillis + " ms"); + return true; + } + + final long waitTimeMillis = (RESULT_TIMEOUT - elapsedTimeMillis); + + // Fail if we've already exceeded the timeout. + if (waitTimeMillis <= 0) { + if (DEBUG) + Log.w(TAG, "Timed out while waiting for CVOX result"); + return false; + } + try { - if (mResultId == resultId) { - if (DEBUG) - Log.w(TAG, "Received CVOX result"); - return true; - } - if (mResultId > resultId) { - if (DEBUG) - Log.w(TAG, "Obsolete CVOX result"); - return false; - } - final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis; - waitTimeMillis = RESULT_TIMEOUT - elapsedTimeMillis; - if (waitTimeMillis <= 0) { - if (DEBUG) - Log.w(TAG, "Timed out while waiting for CVOX result"); - return false; - } + if (DEBUG) + Log.w(TAG, "Start waiting..."); mResultLock.wait(waitTimeMillis); } catch (InterruptedException ie) { if (DEBUG) Log.w(TAG, "Interrupted while waiting for CVOX result"); - /* ignore */ } } } @@ -827,11 +877,11 @@ class AccessibilityInjector { @SuppressWarnings("unused") public void onResult(String id, String result) { if (DEBUG) - Log.w(TAG, "Saw CVOX result of '" + result + "'"); - final long resultId; + Log.w(TAG, "Saw CVOX result of '" + result + "' for ID " + id); + final int resultId; try { - resultId = Long.parseLong(id); + resultId = Integer.parseInt(id); } catch (NumberFormatException e) { return; } @@ -840,6 +890,9 @@ class AccessibilityInjector { if (resultId > mResultId) { mResult = Boolean.parseBoolean(result); mResultId = resultId; + } else { + if (DEBUG) + Log.w(TAG, "Result with ID " + resultId + " was stale vesus " + mResultId); } mResultLock.notifyAll(); } diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java index 7d0d0ba..0f8966e 100644 --- a/core/java/android/webkit/WebViewClassic.java +++ b/core/java/android/webkit/WebViewClassic.java @@ -2132,6 +2132,10 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc private void destroyJava() { mCallbackProxy.blockMessages(); + if (mAccessibilityInjector != null) { + mAccessibilityInjector.destroy(); + mAccessibilityInjector = null; + } if (mWebViewCore != null) { // Tell WebViewCore to destroy itself synchronized (this) { @@ -3967,8 +3971,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc // null, and that will be the case mWebView.setCertificate(null); - // reset the flag since we set to true in if need after - // loading is see onPageFinished(Url) if (isAccessibilityInjectionEnabled()) { getAccessibilityInjector().onPageStarted(url); } @@ -5397,7 +5399,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc if (mWebView.hasWindowFocus()) setActive(true); if (isAccessibilityInjectionEnabled()) { - getAccessibilityInjector().addAccessibilityApisIfNecessary(); + getAccessibilityInjector().toggleAccessibilityFeedback(true); } updateHwAccelerated(); @@ -5410,11 +5412,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc if (mWebView.hasWindowFocus()) setActive(false); if (isAccessibilityInjectionEnabled()) { - getAccessibilityInjector().removeAccessibilityApisIfNecessary(); - } else { - // Ensure the injector is cleared if we're detaching from the window - // and accessibility is disabled. - mAccessibilityInjector = null; + getAccessibilityInjector().toggleAccessibilityFeedback(false); } updateHwAccelerated(); |