Merge to M65: Android Accessibility: Avoiding Infinite loop of FrameLayouts in a11y tree

Initially https://chromium-review.googlesource.com/c/chromium/src/+/729145
ContentViewCore.java#b1735 shows that if the mWebContentsAccessibility was null or
not enabled, we just create it and enable it. The return value was null for these 2 cases.

This CL tries to get that behavior back and avoid loops.

Bug: 805014
Change-Id: I4c880cf3f6fc482559b3cc81a3afbe22ae2fd199
Reviewed-on: https://chromium-review.googlesource.com/927861
Reviewed-by: Dominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/branch-heads/3325@{#527}
Cr-Branched-From: bc084a8b5afa3744a74927344e304c02ae54189f-refs/heads/master@{#530369}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java
index 8cab0a6..2ed7781 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java
@@ -13,7 +13,6 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.LargeTest;
 import android.support.test.filters.SmallTest;
-import android.view.accessibility.AccessibilityNodeProvider;
 import android.webkit.JavascriptInterface;
 
 import org.junit.After;
@@ -30,6 +29,7 @@
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.content_public.browser.ImeAdapter;
+import org.chromium.content_public.browser.WebContentsAccessibility;
 import org.chromium.content_public.common.ContentUrlConstants;
 
 /**
@@ -165,27 +165,30 @@
 
         TestAwContentsClient client = new TestAwContentsClient();
         AwTestContainerView containerViews[] = new AwTestContainerView[MAX_IDLE_INSTANCES + 1];
-        AccessibilityNodeProvider providers[] =
-                new AccessibilityNodeProvider[MAX_IDLE_INSTANCES + 1];
         for (int i = 0; i < containerViews.length; i++) {
             final AwTestContainerView containerView =
                     mActivityTestRule.createAwTestContainerViewOnMainSync(client);
             containerViews[i] = containerView;
             mActivityTestRule.loadUrlAsync(
                     containerViews[i].getAwContents(), ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
-            providers[i] = ThreadUtils.runOnUiThreadBlocking(() -> {
+            ThreadUtils.runOnUiThreadBlocking(() -> {
+                StrongRefTestContext context =
+                        new StrongRefTestContext(mActivityTestRule.getActivity());
+                WebContentsAccessibility webContentsA11y = WebContentsAccessibility.create(
+                        context, containerView, containerView.getWebContents(), true);
                 containerView.getContentViewCore().setAccessibilityState(true);
-                return containerView.getAccessibilityNodeProvider();
+                // Enable a11y for testing.
+                WebContentsAccessibility.setAccessibilityEnabledForTesting();
+                // Initialize native object.
+                containerView.getAccessibilityNodeProvider();
+                Assert.assertTrue(webContentsA11y.isAccessibilityEnabled());
             });
-            Assert.assertNotNull(providers[i]);
         }
 
         for (int i = 0; i < containerViews.length; i++) {
             containerViews[i] = null;
-            providers[i] = null;
         }
         containerViews = null;
-        providers = null;
         removeAllViews();
         gcAndCheckAllAwContentsDestroyed();
     }
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java
index 4e535fa..7cb6c1d 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java
@@ -1139,6 +1139,7 @@
         }
         if (!mWebContentsAccessibility.isEnabled()) {
             mWebContentsAccessibility.enable();
+            return null;
         }
         return mWebContentsAccessibility.getAccessibilityNodeProvider();
     }
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibility.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibility.java
index 5cc1cf4..82f800c 100644
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibility.java
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibility.java
@@ -23,6 +23,7 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeProvider;
 
+import org.chromium.base.VisibleForTesting;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.content.browser.RenderCoordinates;
@@ -139,7 +140,8 @@
     /**
      * Pretend that accessibility is enabled, for testing.
      */
-    static void setAccessibilityEnabledForTesting() {
+    @VisibleForTesting
+    public static void setAccessibilityEnabledForTesting() {
         sAccessibilityEnabledForTesting = true;
     }
 
@@ -651,7 +653,7 @@
         return bundle;
     }
 
-    private boolean isAccessibilityEnabled() {
+    public boolean isAccessibilityEnabled() {
         return sAccessibilityEnabledForTesting || mAccessibilityManager.isEnabled();
     }
 
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java
index 549a5e5..029a65d 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java
@@ -22,7 +22,6 @@
 import android.view.accessibility.AccessibilityNodeProvider;
 
 import org.junit.Assert;
-import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -46,11 +45,6 @@
     @Rule
     public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule();
 
-    @Before
-    public void setUp() throws Exception {
-        WebContentsAccessibility.setAccessibilityEnabledForTesting();
-    }
-
     /**
      * Helper class that can be used to wait until an AccessibilityEvent is fired on a view.
      */
@@ -79,7 +73,7 @@
     private AccessibilityNodeProvider enableAccessibilityAndWaitForNodeProvider() {
         final ContentViewCore contentViewCore = mActivityTestRule.getContentViewCore();
         contentViewCore.setAccessibilityState(true);
-
+        WebContentsAccessibility.setAccessibilityEnabledForTesting();
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
@@ -113,6 +107,7 @@
         // Get the AccessibilityNodeProvider.
         ContentViewCore contentViewCore = mActivityTestRule.getContentViewCore();
         contentViewCore.setAccessibilityState(true);
+        WebContentsAccessibility.setAccessibilityEnabledForTesting();
         AccessibilityNodeProvider provider = contentViewCore.getAccessibilityNodeProvider();
 
         // Wait until we find a node in the accessibility tree with the text "Text".