1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.android_webview.test; 6 7 import android.graphics.Picture; 8 import android.os.Handler; 9 import android.os.Looper; 10 import android.test.suitebuilder.annotation.SmallTest; 11 12 import org.chromium.android_webview.AwContentsClientCallbackHelper; 13 import org.chromium.android_webview.test.TestAwContentsClient.OnDownloadStartHelper; 14 import org.chromium.android_webview.test.TestAwContentsClient.OnReceivedLoginRequestHelper; 15 import org.chromium.android_webview.test.TestAwContentsClient.PictureListenerHelper; 16 import org.chromium.base.test.util.Feature; 17 import org.chromium.content.browser.test.util.CallbackHelper; 18 import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnPageStartedHelper; 19 import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnReceivedErrorHelper; 20 21 import java.util.concurrent.Callable; 22 23 /** 24 * Test suite for AwContentsClientCallbackHelper. 25 */ 26 public class AwContentsClientCallbackHelperTest extends AwTestBase { 27 /** 28 * Callback helper for OnLoadedResource. 29 */ 30 public static class OnLoadResourceHelper extends CallbackHelper { 31 private String mLastLoadedResource; 32 33 public String getLastLoadedResource() { 34 assert getCallCount() > 0; 35 return mLastLoadedResource; 36 } 37 38 public void notifyCalled(String url) { 39 mLastLoadedResource = url; 40 notifyCalled(); 41 } 42 } 43 44 /** 45 * TestAwContentsClient extended with OnLoadResourceHelper. 46 */ 47 public static class TestAwContentsClient 48 extends org.chromium.android_webview.test.TestAwContentsClient { 49 50 private final OnLoadResourceHelper mOnLoadResourceHelper; 51 52 public TestAwContentsClient() { 53 super(); 54 mOnLoadResourceHelper = new OnLoadResourceHelper(); 55 } 56 57 public OnLoadResourceHelper getOnLoadResourceHelper() { 58 return mOnLoadResourceHelper; 59 } 60 61 @Override 62 public void onLoadResource(String url) { 63 mOnLoadResourceHelper.notifyCalled(url); 64 } 65 } 66 67 static final int PICTURE_TIMEOUT = 5000; 68 static final String TEST_URL = "www.example.com"; 69 static final String REALM = "www.example.com"; 70 static final String ACCOUNT = "account"; 71 static final String ARGS = "args"; 72 static final String USER_AGENT = "userAgent"; 73 static final String CONTENT_DISPOSITION = "contentDisposition"; 74 static final String MIME_TYPE = "mimeType"; 75 static final int CONTENT_LENGTH = 42; 76 77 static final float NEW_SCALE = 1.0f; 78 static final float OLD_SCALE = 2.0f; 79 static final int ERROR_CODE = 2; 80 static final String ERROR_MESSAGE = "A horrible thing has occurred!"; 81 82 private TestAwContentsClient mContentsClient; 83 private AwContentsClientCallbackHelper mClientHelper; 84 private Looper mLooper; 85 86 @Override 87 protected void setUp() throws Exception { 88 super.setUp(); 89 mLooper = Looper.getMainLooper(); 90 mContentsClient = new TestAwContentsClient(); 91 mClientHelper = new AwContentsClientCallbackHelper(mLooper, mContentsClient); 92 } 93 94 @Feature({"AndroidWebView"}) 95 @SmallTest 96 public void testOnLoadResource() throws Exception { 97 OnLoadResourceHelper loadResourceHelper = mContentsClient.getOnLoadResourceHelper(); 98 99 int onLoadResourceCount = loadResourceHelper.getCallCount(); 100 mClientHelper.postOnLoadResource(TEST_URL); 101 loadResourceHelper.waitForCallback(onLoadResourceCount); 102 assertEquals(TEST_URL, loadResourceHelper.getLastLoadedResource()); 103 } 104 105 @Feature({"AndroidWebView"}) 106 @SmallTest 107 public void testOnPageStarted() throws Exception { 108 OnPageStartedHelper pageStartedHelper = mContentsClient.getOnPageStartedHelper(); 109 110 int onPageStartedCount = pageStartedHelper.getCallCount(); 111 mClientHelper.postOnPageStarted(TEST_URL); 112 pageStartedHelper.waitForCallback(onPageStartedCount); 113 assertEquals(TEST_URL, pageStartedHelper.getUrl()); 114 } 115 116 @Feature({"AndroidWebView"}) 117 @SmallTest 118 public void testOnDownloadStart() throws Exception { 119 OnDownloadStartHelper downloadStartHelper = mContentsClient.getOnDownloadStartHelper(); 120 121 int onDownloadStartCount = downloadStartHelper.getCallCount(); 122 mClientHelper.postOnDownloadStart(TEST_URL, USER_AGENT, CONTENT_DISPOSITION, 123 MIME_TYPE, CONTENT_LENGTH); 124 downloadStartHelper.waitForCallback(onDownloadStartCount); 125 assertEquals(TEST_URL, downloadStartHelper.getUrl()); 126 assertEquals(USER_AGENT, downloadStartHelper.getUserAgent()); 127 assertEquals(CONTENT_DISPOSITION, downloadStartHelper.getContentDisposition()); 128 assertEquals(MIME_TYPE, downloadStartHelper.getMimeType()); 129 assertEquals(CONTENT_LENGTH, downloadStartHelper.getContentLength()); 130 } 131 132 @Feature({"AndroidWebView"}) 133 @SmallTest 134 public void testOnNewPicture() throws Exception { 135 final PictureListenerHelper pictureListenerHelper = 136 mContentsClient.getPictureListenerHelper(); 137 138 final Picture thePicture = new Picture(); 139 140 final Callable<Picture> pictureProvider = new Callable<Picture>() { 141 @Override 142 public Picture call() { 143 return thePicture; 144 } 145 }; 146 147 // AwContentsClientCallbackHelper rate limits photo callbacks so two posts in close 148 // succession should only result in one callback. 149 final int onNewPictureCount = pictureListenerHelper.getCallCount(); 150 // To trip the rate limiting the second postNewPicture call needs to happen 151 // before mLooper processes the first. To do this we run both posts as a single block 152 // and we do it in the thread that is processes the callbacks (mLooper). 153 Handler mainHandler = new Handler(mLooper); 154 Runnable postPictures = new Runnable() { 155 @Override 156 public void run() { 157 mClientHelper.postOnNewPicture(pictureProvider); 158 mClientHelper.postOnNewPicture(pictureProvider); 159 } 160 }; 161 mainHandler.post(postPictures); 162 163 // We want to check that one and only one callback is fired, 164 // First we wait for the first call back to complete, this ensures that both posts have 165 // finished. 166 pictureListenerHelper.waitForCallback(onNewPictureCount); 167 168 // Then we post a runnable on the callback handler thread. Since both posts have happened 169 // and the first callback has happened a second callback (if it exists) must be 170 // in the queue before this runnable. 171 getInstrumentation().runOnMainSync(new Runnable() { 172 @Override 173 public void run() { 174 } 175 }); 176 177 // When that runnable has finished we assert that one and only on callback happened. 178 assertEquals(thePicture, pictureListenerHelper.getPicture()); 179 assertEquals(onNewPictureCount + 1, pictureListenerHelper.getCallCount()); 180 } 181 182 @Feature({"AndroidWebView"}) 183 @SmallTest 184 public void testOnReceivedLoginRequest() throws Exception { 185 OnReceivedLoginRequestHelper receivedLoginRequestHelper = 186 mContentsClient.getOnReceivedLoginRequestHelper(); 187 188 int onReceivedLoginRequestCount = receivedLoginRequestHelper.getCallCount(); 189 mClientHelper.postOnReceivedLoginRequest(REALM, ACCOUNT, ARGS); 190 receivedLoginRequestHelper.waitForCallback(onReceivedLoginRequestCount); 191 assertEquals(REALM, receivedLoginRequestHelper.getRealm()); 192 assertEquals(ACCOUNT, receivedLoginRequestHelper.getAccount()); 193 assertEquals(ARGS, receivedLoginRequestHelper.getArgs()); 194 } 195 196 @Feature({"AndroidWebView"}) 197 @SmallTest 198 public void testOnReceivedError() throws Exception { 199 OnReceivedErrorHelper receivedErrorHelper = 200 mContentsClient.getOnReceivedErrorHelper(); 201 202 int onReceivedErrorCount = receivedErrorHelper.getCallCount(); 203 mClientHelper.postOnReceivedError(ERROR_CODE, ERROR_MESSAGE, TEST_URL); 204 receivedErrorHelper.waitForCallback(onReceivedErrorCount); 205 assertEquals(ERROR_CODE, receivedErrorHelper.getErrorCode()); 206 assertEquals(ERROR_MESSAGE, receivedErrorHelper.getDescription()); 207 assertEquals(TEST_URL, receivedErrorHelper.getFailingUrl()); 208 } 209 210 @Feature({"AndroidWebView"}) 211 @SmallTest 212 public void testOnScaleChangedScaled() throws Exception { 213 TestAwContentsClient.OnScaleChangedHelper scaleChangedHelper = 214 mContentsClient.getOnScaleChangedHelper(); 215 216 int onScaleChangeCount = scaleChangedHelper.getCallCount(); 217 mClientHelper.postOnScaleChangedScaled(OLD_SCALE, NEW_SCALE); 218 scaleChangedHelper.waitForCallback(onScaleChangeCount); 219 assertEquals(OLD_SCALE, scaleChangedHelper.getOldScale()); 220 assertEquals(NEW_SCALE, scaleChangedHelper.getNewScale()); 221 } 222 } 223