summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
authorCharles Chen <clchen@google.com>2012-10-12 13:46:08 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-10-12 13:46:09 -0700
commit4c38e24afb0fe68d6e9f6e924e6426808be2611a (patch)
treee58b7690c87227ac2e866fd90163a4e94a7dbdd0 /core/java
parentc378656d5e0e686d806661bc271de3c7b1726430 (diff)
parent03e636f33dfdb2f9438f06997a52b43291a83e41 (diff)
downloadframeworks_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.java127
-rw-r--r--core/java/android/webkit/WebViewClassic.java14
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();