Loading core/java/android/webkit/AccessibilityInjector.java +90 −37 Original line number Diff line number Diff line Loading @@ -98,8 +98,11 @@ class AccessibilityInjector { private static final String ACCESSIBILITY_ANDROIDVOX_TEMPLATE = "(function() {" + " 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 {" + Loading @@ -111,8 +114,11 @@ class AccessibilityInjector { private static final String TOGGLE_CVOX_TEMPLATE = "javascript:(function() {" + " 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);" + " }" + "})();"; Loading @@ -131,34 +137,61 @@ class AccessibilityInjector { mAccessibilityManager = AccessibilityManager.getInstance(mContext); } /** * 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; Loading Loading @@ -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(); } /** Loading Loading @@ -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; Loading Loading @@ -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(); while (true) { try { if (mResultId == resultId) { if (DEBUG) Log.w(TAG, "Received CVOX result"); return true; } 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, "Obsolete CVOX result"); Log.w(TAG, "Aborted CVOX result"); return false; } final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis; waitTimeMillis = RESULT_TIMEOUT - elapsedTimeMillis; 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 (DEBUG) Log.w(TAG, "Start waiting..."); mResultLock.wait(waitTimeMillis); } catch (InterruptedException ie) { if (DEBUG) Log.w(TAG, "Interrupted while waiting for CVOX result"); /* ignore */ } } } Loading @@ -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; } Loading @@ -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(); } Loading core/java/android/webkit/WebViewClassic.java +6 −8 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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); } Loading Loading @@ -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(); Loading @@ -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(); Loading Loading
core/java/android/webkit/AccessibilityInjector.java +90 −37 Original line number Diff line number Diff line Loading @@ -98,8 +98,11 @@ class AccessibilityInjector { private static final String ACCESSIBILITY_ANDROIDVOX_TEMPLATE = "(function() {" + " 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 {" + Loading @@ -111,8 +114,11 @@ class AccessibilityInjector { private static final String TOGGLE_CVOX_TEMPLATE = "javascript:(function() {" + " 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);" + " }" + "})();"; Loading @@ -131,34 +137,61 @@ class AccessibilityInjector { mAccessibilityManager = AccessibilityManager.getInstance(mContext); } /** * 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; Loading Loading @@ -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(); } /** Loading Loading @@ -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; Loading Loading @@ -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(); while (true) { try { if (mResultId == resultId) { if (DEBUG) Log.w(TAG, "Received CVOX result"); return true; } 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, "Obsolete CVOX result"); Log.w(TAG, "Aborted CVOX result"); return false; } final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis; waitTimeMillis = RESULT_TIMEOUT - elapsedTimeMillis; 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 (DEBUG) Log.w(TAG, "Start waiting..."); mResultLock.wait(waitTimeMillis); } catch (InterruptedException ie) { if (DEBUG) Log.w(TAG, "Interrupted while waiting for CVOX result"); /* ignore */ } } } Loading @@ -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; } Loading @@ -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(); } Loading
core/java/android/webkit/WebViewClassic.java +6 −8 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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); } Loading Loading @@ -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(); Loading @@ -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(); Loading