Bug 1459301 - 1. Wait on sessions opened through onNewSession response; r?snorp
The session returned through the onNewSession response is opened
internally by GV. GeckoSessionTestRule should trap that and wait on the
newly opened session, just like we do for any other session, so that
this internal open operation is transparent to the test.
MozReview-Commit-ID: HOvEsSVZufS
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
@@ -2,16 +2,17 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.geckoview.test.rule;
import org.mozilla.gecko.gfx.GeckoDisplay;
import org.mozilla.geckoview.BuildConfig;
+import org.mozilla.geckoview.GeckoResponse;
import org.mozilla.geckoview.GeckoRuntime;
import org.mozilla.geckoview.GeckoRuntimeSettings;
import org.mozilla.geckoview.GeckoSession;
import org.mozilla.geckoview.GeckoSessionSettings;
import org.mozilla.geckoview.test.rdp.Actor;
import org.mozilla.geckoview.test.rdp.RDPConnection;
import org.mozilla.geckoview.test.rdp.Tab;
import org.mozilla.geckoview.test.util.Callbacks;
@@ -86,25 +87,25 @@ public class GeckoSessionTestRule extend
private static final long DEFAULT_ARM_DEVICE_TIMEOUT_MILLIS = 30000;
private static final long DEFAULT_ARM_EMULATOR_TIMEOUT_MILLIS = 120000;
private static final long DEFAULT_X86_DEVICE_TIMEOUT_MILLIS = 30000;
private static final long DEFAULT_X86_EMULATOR_TIMEOUT_MILLIS = 5000;
private static final long DEFAULT_IDE_DEBUG_TIMEOUT_MILLIS = 86400000;
public static final String APK_URI_PREFIX = "resource://android/";
- private static final Method sOnLocationChange;
private static final Method sOnPageStop;
+ private static final Method sOnNewSession;
static {
try {
- sOnLocationChange = GeckoSession.NavigationDelegate.class.getMethod(
- "onLocationChange", GeckoSession.class, String.class);
sOnPageStop = GeckoSession.ProgressDelegate.class.getMethod(
"onPageStop", GeckoSession.class, boolean.class);
+ sOnNewSession = GeckoSession.NavigationDelegate.class.getMethod(
+ "onNewSession", GeckoSession.class, String.class, GeckoResponse.class);
} catch (final NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
/**
* Specify the timeout for any of the wait methods, in milliseconds, relative to
* {@link #DEFAULT_TIMEOUT_MILLIS}. When the default timeout scales to account
@@ -901,16 +902,35 @@ public class GeckoSessionTestRule extend
records.add(new CallRecord(session, method, args));
call = waitDelegates.prepareMethodCall(session, method);
if (call == null) {
call = testDelegates.prepareMethodCall(session, method);
}
}
+ if (call != null && sOnNewSession.equals(method)) {
+ // We're delegating an onNewSession call.
+ // Make sure we wait on the newly opened session, if any.
+ final GeckoSession oldSession = (GeckoSession) args[0];
+ @SuppressWarnings("unchecked")
+ final GeckoResponse<GeckoSession> realResponse =
+ (GeckoResponse<GeckoSession>) args[2];
+ args[2] = new GeckoResponse<GeckoSession>() {
+ @Override
+ public void respond(final GeckoSession newSession) {
+ realResponse.respond(newSession);
+ // `realResponse` has opened the session at this point, so wait on it.
+ if (oldSession.isOpen() && newSession != null) {
+ GeckoSessionTestRule.this.waitForOpenSession(newSession);
+ }
+ }
+ };
+ }
+
try {
mCurrentMethodCall = call;
return method.invoke((call != null) ? call.target
: Callbacks.Default.INSTANCE, args);
} catch (final IllegalAccessException | InvocationTargetException e) {
throw unwrapRuntimeException(e);
} finally {
mCurrentMethodCall = null;
@@ -960,16 +980,20 @@ public class GeckoSessionTestRule extend
/**
* Call open() on a session, and ensure it's ready for use by the test. In particular,
* remove any extra calls recorded as part of opening the session.
*
* @param session Session to open.
*/
public void openSession(final GeckoSession session) {
session.open(sRuntime);
+ waitForOpenSession(session);
+ }
+
+ /* package */ void waitForOpenSession(final GeckoSession session) {
waitForInitialLoad(session);
if (mWithDevTools) {
if (sRDPConnection == null) {
final String dataDir = InstrumentationRegistry.getTargetContext()
.getApplicationInfo().dataDir;
final LocalSocketAddress address = new LocalSocketAddress(
dataDir + "/firefox-debugger-socket",
@@ -979,47 +1003,33 @@ public class GeckoSessionTestRule extend
}
final Tab tab = sRDPConnection.getMostRecentTab();
tab.attach();
mRDPTabs.put(session, tab);
}
}
private void waitForInitialLoad(final GeckoSession session) {
- // We receive an initial about:blank load; don't expose that to the test.
- // The about:blank load is bounded by onLocationChange and onPageStop calls,
- // so find the first about:blank onLocationChange, then the next onPageStop,
- // and ignore everything in-between from that session.
+ // We receive an initial about:blank load; don't expose that to the test. The initial
+ // load ends with the first onPageStop call, so ignore everything from the session
+ // until the first onPageStop call.
try {
// We cannot detect initial page load without progress delegate.
assertThat("ProgressDelegate cannot be null-delegate when opening session",
GeckoSession.ProgressDelegate.class, not(isIn(mNullDelegates)));
- // If navigation delegate is a null-delegate, instead of looking for
- // onLocationChange(), start with the first call that targets this session.
- final boolean nullNavigation = mNullDelegates.contains(
- GeckoSession.NavigationDelegate.class);
-
mCallRecordHandler = new CallRecordHandler() {
- private boolean mFoundStart = false;
-
@Override
public boolean handleCall(final Method method, final Object[] args) {
- if (!mFoundStart && session.equals(args[0]) && (nullNavigation ||
- (sOnLocationChange.equals(method) && "about:blank".equals(args[1])))) {
- mFoundStart = true;
- return true;
- } else if (mFoundStart && session.equals(args[0])) {
- if (sOnPageStop.equals(method)) {
- mCallRecordHandler = null;
- }
- return true;
+ final boolean matching = session.equals(args[0]);
+ if (matching && sOnPageStop.equals(method)) {
+ mCallRecordHandler = null;
}
- return false;
+ return matching;
}
};
do {
loopUntilIdle(getDefaultTimeoutMillis());
} while (mCallRecordHandler != null);
} finally {