Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3184787c authored by Charles Chen's avatar Charles Chen Committed by Android Git Automerger
Browse files

am 935db6c5: am e228b5b9: am 4c38e24a: Merge "Don\'t alter accessibility JS...

am 935db6c5: am e228b5b9: am 4c38e24a: Merge "Don\'t alter accessibility JS APIs unless a page is about to load." into jb-mr1-dev

* commit '935db6c5':
  Don't alter accessibility JS APIs unless a page is about to load.
parents 7a6dca42 935db6c5
Loading
Loading
Loading
Loading
+90 −37
Original line number Diff line number Diff line
@@ -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 {" +
@@ -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);" +
                    "  }" +
                    "})();";
@@ -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;
@@ -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();
            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 */
                }
            }
        }
@@ -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();
            }
+6 −8
Original line number Diff line number Diff line
@@ -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();