Portals: Add test for touch transfer across portal reactivation

Bug: 914376
Change-Id: I1c14e678e3b34989492992cdd273ce3b0feba14a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1674494
Reviewed-by: David Trainor <dtrainor@chromium.org>
Reviewed-by: Kevin McNee <mcnee@chromium.org>
Commit-Queue: Adithya Srinivasan <adithyas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#679744}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/portals/PortalsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/portals/PortalsTest.java
index 5c543e4..1895462 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/portals/PortalsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/portals/PortalsTest.java
@@ -278,4 +278,48 @@
         WebContents contents = mActivityTestRule.getWebContents();
         Assert.assertTrue(Coordinates.createFor(contents).getScrollYPixInt() > 0);
     }
+
+    @Test
+    @MediumTest
+    @Feature({"Portals"})
+    public void testTouchTransferAfterReactivation() throws Exception {
+        mActivityTestRule.startMainActivityWithURL(mTestServer.getURL(
+                "/chrome/test/data/android/portals/touch-transfer-after-reactivation.html"));
+
+        ChromeActivity activity = mActivityTestRule.getActivity();
+        Tab tab = activity.getActivityTab();
+        View contentView = tab.getContentView();
+
+        TabContentsSwapObserver swapObserver = new TabContentsSwapObserver();
+        CallbackHelper swapWaiter = swapObserver.getCallbackHelper();
+        tab.addObserver(swapObserver);
+        int currSwapCount = swapWaiter.getCallCount();
+
+        int dragStartX = 30;
+        int dragStartY = contentView.getHeight() / 2;
+        int dragEndX = dragStartX;
+        int dragEndY = 30;
+        long downTime = System.currentTimeMillis();
+
+        // Initial touch to trigger activation.
+        TouchCommon.dragStart(activity, dragStartX, dragStartY, downTime);
+
+        // Wait for first activation.
+        swapWaiter.waitForCallback(currSwapCount, 1);
+
+        LayoutAfterTabContentsSwappedObserver layoutObserver =
+                new LayoutAfterTabContentsSwappedObserver(tab);
+        CallbackHelper layoutWaiter = layoutObserver.getCallbackHelper();
+        int currLayoutCount = layoutWaiter.getCallCount();
+
+        // Wait for the first layout after second activation (reactivation of predecessor).
+        layoutWaiter.waitForCallback(currLayoutCount, 1);
+
+        // Continue and finish drag.
+        TouchCommon.dragTo(activity, dragStartX, dragEndX, dragStartY, dragEndY, 100, downTime);
+        TouchCommon.dragEnd(activity, dragEndX, dragEndY, downTime);
+
+        WebContents contents = mActivityTestRule.getWebContents();
+        Assert.assertTrue(Coordinates.createFor(contents).getScrollYPixInt() > 0);
+    }
 }
diff --git a/chrome/test/data/android/portals/activate-predecessor.html b/chrome/test/data/android/portals/activate-predecessor.html
new file mode 100644
index 0000000..f07582df
--- /dev/null
+++ b/chrome/test/data/android/portals/activate-predecessor.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<body>
+  <script>
+    window.onportalactivate = e => {
+      var portal = e.adoptPredecessor();
+      document.body.appendChild(portal);
+      portal.activate();
+    }
+  </script>
+</body>
+</html>
diff --git a/chrome/test/data/android/portals/touch-transfer-after-reactivation.html b/chrome/test/data/android/portals/touch-transfer-after-reactivation.html
new file mode 100644
index 0000000..b877f47
--- /dev/null
+++ b/chrome/test/data/android/portals/touch-transfer-after-reactivation.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+    #scroller {
+      height: 2000px;
+      width: 300px;
+      background-color: blue;
+    }
+  </style>
+</head>
+<body>
+  <div id="scroller"></div>
+  <portal src="activate-predecessor.html"></portal>
+  <script>
+    document.body.addEventListener('touchstart', e => {
+      var portal = document.querySelector('portal');
+      portal.activate().then(() => {
+        document.body.removeChild(portal);
+      });
+    }, {passive: false, once: true});
+  </script>
+</body>
+</html>