blob: ffb21313b45f802140fb5cd2bd6b6966b608c515 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.android_webview.test;
import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.SINGLE_PROCESS;
import android.graphics.Picture;
import android.os.Handler;
import android.os.Looper;
import android.support.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.android_webview.AwContentsClient;
import org.chromium.android_webview.AwContentsClientCallbackHelper;
import org.chromium.android_webview.test.TestAwContentsClient.OnDownloadStartHelper;
import org.chromium.android_webview.test.TestAwContentsClient.OnLoadResourceHelper;
import org.chromium.android_webview.test.TestAwContentsClient.OnReceivedLoginRequestHelper;
import org.chromium.android_webview.test.TestAwContentsClient.PictureListenerHelper;
import org.chromium.base.test.util.Batch;
import org.chromium.base.test.util.CallbackHelper;
import org.chromium.base.test.util.Feature;
import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer.OnPageStartedHelper;
import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer.OnReceivedErrorHelper;
import java.util.concurrent.Callable;
/**
* Test suite for AwContentsClientCallbackHelper.
*/
@RunWith(AwJUnit4ClassRunner.class)
@OnlyRunIn(SINGLE_PROCESS) // These are unit tests. No need to repeat for multiprocess.
@Batch(Batch.UNIT_TESTS)
public class AwContentsClientCallbackHelperTest {
@Rule
public AwActivityTestRule mActivityTestRule = new AwActivityTestRule();
private static class TestCancelCallbackPoller
implements AwContentsClientCallbackHelper.CancelCallbackPoller {
private boolean mCancelled;
private final CallbackHelper mCallbackHelper = new CallbackHelper();
public void setCancelled() {
mCancelled = true;
}
public CallbackHelper getCallbackHelper() {
return mCallbackHelper;
}
@Override
public boolean shouldCancelAllCallbacks() {
mCallbackHelper.notifyCalled();
return mCancelled;
}
}
static final int PICTURE_TIMEOUT = 5000;
static final String TEST_URL = "www.example.com";
static final String REALM = "www.example.com";
static final String ACCOUNT = "account";
static final String ARGS = "args";
static final String USER_AGENT = "userAgent";
static final String CONTENT_DISPOSITION = "contentDisposition";
static final String MIME_TYPE = "mimeType";
static final int CONTENT_LENGTH = 42;
static final float NEW_SCALE = 1.0f;
static final float OLD_SCALE = 2.0f;
static final int ERROR_CODE = 2;
static final String ERROR_MESSAGE = "A horrible thing has occurred!";
private TestAwContentsClient mContentsClient;
private AwContentsClientCallbackHelper mClientHelper;
private TestCancelCallbackPoller mCancelCallbackPoller;
private Looper mLooper;
@Before
public void setUp() {
mLooper = Looper.getMainLooper();
mContentsClient = new TestAwContentsClient();
mClientHelper = new AwContentsClientCallbackHelper(mLooper, mContentsClient);
mCancelCallbackPoller = new TestCancelCallbackPoller();
mClientHelper.setCancelCallbackPoller(mCancelCallbackPoller);
}
@Test
@Feature({"AndroidWebView"})
@SmallTest
public void testOnLoadResource() throws Exception {
OnLoadResourceHelper loadResourceHelper = mContentsClient.getOnLoadResourceHelper();
int onLoadResourceCount = loadResourceHelper.getCallCount();
mClientHelper.postOnLoadResource(TEST_URL);
loadResourceHelper.waitForCallback(onLoadResourceCount);
Assert.assertEquals(TEST_URL, loadResourceHelper.getLastLoadedResource());
}
@Test
@Feature({"AndroidWebView"})
@SmallTest
public void testOnPageStarted() throws Exception {
OnPageStartedHelper pageStartedHelper = mContentsClient.getOnPageStartedHelper();
int onPageStartedCount = pageStartedHelper.getCallCount();
mClientHelper.postOnPageStarted(TEST_URL);
pageStartedHelper.waitForCallback(onPageStartedCount);
Assert.assertEquals(TEST_URL, pageStartedHelper.getUrl());
}
@Test
@Feature({"AndroidWebView"})
@SmallTest
public void testOnDownloadStart() throws Exception {
OnDownloadStartHelper downloadStartHelper = mContentsClient.getOnDownloadStartHelper();
int onDownloadStartCount = downloadStartHelper.getCallCount();
mClientHelper.postOnDownloadStart(TEST_URL, USER_AGENT, CONTENT_DISPOSITION,
MIME_TYPE, CONTENT_LENGTH);
downloadStartHelper.waitForCallback(onDownloadStartCount);
Assert.assertEquals(TEST_URL, downloadStartHelper.getUrl());
Assert.assertEquals(USER_AGENT, downloadStartHelper.getUserAgent());
Assert.assertEquals(CONTENT_DISPOSITION, downloadStartHelper.getContentDisposition());
Assert.assertEquals(MIME_TYPE, downloadStartHelper.getMimeType());
Assert.assertEquals(CONTENT_LENGTH, downloadStartHelper.getContentLength());
}
@Test
@Feature({"AndroidWebView"})
@SmallTest
public void testOnNewPicture() throws Exception {
final PictureListenerHelper pictureListenerHelper =
mContentsClient.getPictureListenerHelper();
final Picture thePicture = new Picture();
final Callable<Picture> pictureProvider = () -> thePicture;
// AwContentsClientCallbackHelper rate limits photo callbacks so two posts in close
// succession should only result in one callback.
final int onNewPictureCount = pictureListenerHelper.getCallCount();
// To trip the rate limiting the second postNewPicture call needs to happen
// before mLooper processes the first. To do this we run both posts as a single block
// and we do it in the thread that is processes the callbacks (mLooper).
Handler mainHandler = new Handler(mLooper);
Runnable postPictures = () -> {
mClientHelper.postOnNewPicture(pictureProvider);
mClientHelper.postOnNewPicture(pictureProvider);
};
mainHandler.post(postPictures);
// We want to check that one and only one callback is fired,
// First we wait for the first call back to complete, this ensures that both posts have
// finished.
pictureListenerHelper.waitForCallback(onNewPictureCount);
// Then we post a runnable on the callback handler thread. Since both posts have happened
// and the first callback has happened a second callback (if it exists) must be
// in the queue before this runnable.
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
});
// When that runnable has finished we assert that one and only on callback happened.
Assert.assertEquals(thePicture, pictureListenerHelper.getPicture());
Assert.assertEquals(onNewPictureCount + 1, pictureListenerHelper.getCallCount());
}
@Test
@Feature({"AndroidWebView"})
@SmallTest
public void testOnReceivedLoginRequest() throws Exception {
OnReceivedLoginRequestHelper receivedLoginRequestHelper =
mContentsClient.getOnReceivedLoginRequestHelper();
int onReceivedLoginRequestCount = receivedLoginRequestHelper.getCallCount();
mClientHelper.postOnReceivedLoginRequest(REALM, ACCOUNT, ARGS);
receivedLoginRequestHelper.waitForCallback(onReceivedLoginRequestCount);
Assert.assertEquals(REALM, receivedLoginRequestHelper.getRealm());
Assert.assertEquals(ACCOUNT, receivedLoginRequestHelper.getAccount());
Assert.assertEquals(ARGS, receivedLoginRequestHelper.getArgs());
}
@Test
@Feature({"AndroidWebView"})
@SmallTest
public void testOnReceivedError() throws Exception {
OnReceivedErrorHelper receivedErrorHelper =
mContentsClient.getOnReceivedErrorHelper();
int onReceivedErrorCount = receivedErrorHelper.getCallCount();
AwContentsClient.AwWebResourceRequest request = new AwContentsClient.AwWebResourceRequest();
request.url = TEST_URL;
request.isMainFrame = true;
AwContentsClient.AwWebResourceError error = new AwContentsClient.AwWebResourceError();
error.errorCode = ERROR_CODE;
error.description = ERROR_MESSAGE;
mClientHelper.postOnReceivedError(request, error);
receivedErrorHelper.waitForCallback(onReceivedErrorCount);
Assert.assertEquals(ERROR_CODE, receivedErrorHelper.getErrorCode());
Assert.assertEquals(ERROR_MESSAGE, receivedErrorHelper.getDescription());
Assert.assertEquals(TEST_URL, receivedErrorHelper.getFailingUrl());
}
@Test
@Feature({"AndroidWebView"})
@SmallTest
public void testOnScaleChangedScaled() throws Exception {
TestAwContentsClient.OnScaleChangedHelper scaleChangedHelper =
mContentsClient.getOnScaleChangedHelper();
int onScaleChangeCount = scaleChangedHelper.getCallCount();
mClientHelper.postOnScaleChangedScaled(OLD_SCALE, NEW_SCALE);
scaleChangedHelper.waitForCallback(onScaleChangeCount);
Assert.assertEquals(OLD_SCALE, scaleChangedHelper.getOldScale(), 0);
Assert.assertEquals(NEW_SCALE, scaleChangedHelper.getNewScale(), 0);
}
@Test
@Feature({"AndroidWebView"})
@SmallTest
public void testCancelCallbackPoller() throws Exception {
mCancelCallbackPoller.setCancelled();
CallbackHelper cancelCallbackPollerHelper = mCancelCallbackPoller.getCallbackHelper();
OnPageStartedHelper pageStartedHelper = mContentsClient.getOnPageStartedHelper();
int pollCount = pageStartedHelper.getCallCount();
int onPageStartedCount = pageStartedHelper.getCallCount();
// Post two callbacks.
mClientHelper.postOnPageStarted(TEST_URL);
mClientHelper.postOnPageStarted(TEST_URL);
// Wait for at least one poll.
cancelCallbackPollerHelper.waitForCallback(pollCount);
// Flush main queue.
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
});
// Neither callback should actually happen.
Assert.assertEquals(onPageStartedCount, pageStartedHelper.getCallCount());
}
}