Commit 9a424d2e authored by boliu's avatar boliu Committed by Commit bot

Make GC test catch strong ref from client objects

In the public sdk API, apps should be able to hold a strong WebView
reference from WebChromeClient or WebViewClient, without having to worry
about preventing WebView from gc-ed.

Simulate that behavior in testCreateAndGcManyTimes by having the
AwContentsClient hold a strong reference to AwContents.

And remove the strong ref from AwWebContentsObserver to
make the test pass.

BUG=469803

Review URL: https://codereview.chromium.org/1036893002

Cr-Commit-Position: refs/heads/master@{#322380}
parent ed54867c
......@@ -23,14 +23,14 @@ public class AwWebContentsObserver extends WebContentsObserver {
// reference to an AwWebContentsObserver instance. This is not intentional,
// and should be found and cleaned up.
private final WeakReference<AwContents> mAwContents;
private final AwContentsClient mAwContentsClient;
private final WeakReference<AwContentsClient> mAwContentsClient;
private boolean mStartedNonApiProvisionalLoadInMainFrame = false;
public AwWebContentsObserver(
WebContents webContents, AwContents awContents, AwContentsClient awContentsClient) {
super(webContents);
mAwContents = new WeakReference<AwContents>(awContents);
mAwContentsClient = awContentsClient;
mAwContents = new WeakReference<>(awContents);
mAwContentsClient = new WeakReference<>(awContentsClient);
}
boolean hasStartedNonApiProvisionalLoadInMainFrame() {
......@@ -39,24 +39,28 @@ public class AwWebContentsObserver extends WebContentsObserver {
@Override
public void didFinishLoad(long frameId, String validatedUrl, boolean isMainFrame) {
AwContentsClient client = mAwContentsClient.get();
if (client == null) return;
String unreachableWebDataUrl = AwContentsStatics.getUnreachableWebDataUrl();
boolean isErrorUrl =
unreachableWebDataUrl != null && unreachableWebDataUrl.equals(validatedUrl);
if (isMainFrame && !isErrorUrl) {
mAwContentsClient.onPageFinished(validatedUrl);
client.onPageFinished(validatedUrl);
}
}
@Override
public void didFailLoad(boolean isProvisionalLoad,
boolean isMainFrame, int errorCode, String description, String failingUrl) {
AwContentsClient client = mAwContentsClient.get();
if (client == null) return;
String unreachableWebDataUrl = AwContentsStatics.getUnreachableWebDataUrl();
boolean isErrorUrl =
unreachableWebDataUrl != null && unreachableWebDataUrl.equals(failingUrl);
if (isMainFrame && !isErrorUrl && errorCode == NetError.ERR_ABORTED) {
// Need to call onPageFinished for backwards compatibility with the classic webview.
// See also AwContents.IoThreadClientImpl.onReceivedError.
mAwContentsClient.onPageFinished(failingUrl);
client.onPageFinished(failingUrl);
}
}
......@@ -74,23 +78,30 @@ public class AwWebContentsObserver extends WebContentsObserver {
awContents.insertVisualStateCallback(0, new VisualStateCallback() {
@Override
public void onComplete(long requestId) {
mAwContentsClient.onPageCommitVisible(url);
AwContentsClient client = mAwContentsClient.get();
if (client == null) return;
client.onPageCommitVisible(url);
}
});
}
}
});
}
// This is here to emulate the Classic WebView firing onPageFinished for main frame
// navigations where only the hash fragment changes.
if (isFragmentNavigation) {
mAwContentsClient.onPageFinished(url);
AwContentsClient client = mAwContentsClient.get();
if (client == null) return;
client.onPageFinished(url);
}
}
@Override
public void didNavigateAnyFrame(String url, String baseUrl, boolean isReload) {
mAwContentsClient.doUpdateVisitedHistory(url, isReload);
final AwContentsClient client = mAwContentsClient.get();
if (client == null) return;
client.doUpdateVisitedHistory(url, isReload);
}
@Override
......
......@@ -139,6 +139,14 @@ public class AwContentsTest extends AwTestBase {
new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU));
}
@SuppressFBWarnings("URF_UNREAD_FIELD")
private static class StrongRefTestAwContentsClient extends TestAwContentsClient {
private AwContents mAwContentsStrongRef;
public void setAwContentsStrongRef(AwContents awContents) {
mAwContentsStrongRef = awContents;
}
}
@DisableHardwareAccelerationForTest
@LargeTest
@Feature({"AndroidWebView"})
......@@ -159,7 +167,13 @@ public class AwContentsTest extends AwTestBase {
});
for (int i = 0; i < repetitions; ++i) {
for (int j = 0; j < concurrentInstances; ++j) {
AwTestContainerView view = createAwTestContainerViewOnMainSync(mContentsClient);
final StrongRefTestAwContentsClient client = new StrongRefTestAwContentsClient();
AwTestContainerView view = createAwTestContainerViewOnMainSync(client);
// Embedding app can hold onto a strong ref to the WebView from either WebViewClient
// or WebChromeClient. That should not prevent WebView from gc-ed. We simulate that
// behavior by making the equivalent change here, have AwContentsClient hold a
// strong ref to the AwContents object.
client.setAwContentsStrongRef(view.getAwContents());
loadUrlAsync(view.getAwContents(), "about:blank");
}
assertTrue(AwContents.getNativeInstanceCount() >= concurrentInstances);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment