1 // Copyright 2012 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.
5 package org.chromium.android_webview.test;
7 import android.graphics.Bitmap;
8 import android.graphics.BitmapFactory;
9 import android.test.suitebuilder.annotation.SmallTest;
11 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
13 import org.chromium.android_webview.AwContents;
14 import org.chromium.android_webview.test.util.CommonResources;
15 import org.chromium.content.browser.test.util.CallbackHelper;
16 import org.chromium.net.test.util.TestWebServer;
18 import java.io.InputStream;
20 import java.util.HashMap;
21 import java.util.concurrent.Callable;
24 * Tests for the Favicon and TouchIcon related APIs.
26 public class AwContentsClientFaviconTest extends AwTestBase {
28 private static final String FAVICON1_URL = "/favicon1.png";
29 private static final String FAVICON1_PAGE_URL = "/favicon1.html";
30 private static final String FAVICON1_PAGE_HTML =
31 CommonResources.makeHtmlPageFrom(
32 "<link rel=\"icon\" href=\"" + FAVICON1_URL + "\" />",
35 private static final String TOUCHICON_REL_LINK = "touch.png";
36 private static final String TOUCHICON_REL_LINK_72 = "touch_72.png";
37 private static final String TOUCHICON_REL_URL = "/" + TOUCHICON_REL_LINK;
38 private static final String TOUCHICON_REL_URL_72 = "/" + TOUCHICON_REL_LINK_72;
39 private static final String TOUCHICON_REL_PAGE_HTML =
40 CommonResources.makeHtmlPageFrom(
41 "<link rel=\"apple-touch-icon\" href=\"" + TOUCHICON_REL_URL + "\" />" +
42 "<link rel=\"apple-touch-icon\" sizes=\"72x72\" href=\"" + TOUCHICON_REL_URL_72
46 // Maximum number of milliseconds within which a request to web server is made.
47 private static final long MAX_REQUEST_WAITING_LIMIT_MS = scaleTimeout(500);
49 private static class FaviconHelper extends CallbackHelper {
51 private HashMap<String, Boolean> mTouchIcons = new HashMap<String, Boolean>();
53 public void notifyFavicon(Bitmap icon) {
58 public void notifyTouchIcon(String url, boolean precomposed) {
59 mTouchIcons.put(url, precomposed);
64 private static class TestAwContentsClientBase
65 extends org.chromium.android_webview.test.TestAwContentsClient {
66 FaviconHelper mFaviconHelper = new FaviconHelper();
69 private static class TestAwContentsClientFavicon extends TestAwContentsClientBase {
71 public void onReceivedIcon(Bitmap bitmap) {
72 // We don't inform the API client about the URL of the icon.
73 mFaviconHelper.notifyFavicon(bitmap);
77 private static class TestAwContentsClientTouchIcon extends TestAwContentsClientBase {
79 public void onReceivedTouchIconUrl(String url, boolean precomposed) {
80 mFaviconHelper.notifyTouchIcon(url, precomposed);
84 private TestAwContentsClientBase mContentsClient;
85 private AwContents mAwContents;
86 private TestWebServer mWebServer;
89 protected void setUp() throws Exception {
91 AwContents.setShouldDownloadFavicons();
92 mWebServer = new TestWebServer(false);
95 private void init(TestAwContentsClientBase contentsClient) throws Exception {
96 mContentsClient = contentsClient;
97 AwTestContainerView testContainerView =
98 createAwTestContainerViewOnMainSync(mContentsClient);
99 mAwContents = testContainerView.getAwContents();
103 protected void tearDown() throws Exception {
104 if (mWebServer != null) mWebServer.shutdown();
109 public void testReceiveBasicFavicon() throws Throwable {
110 init(new TestAwContentsClientFavicon());
111 int callCount = mContentsClient.mFaviconHelper.getCallCount();
113 final String faviconUrl = mWebServer.setResponseBase64(FAVICON1_URL,
114 CommonResources.FAVICON_DATA_BASE64, CommonResources.getImagePngHeaders(true));
115 final String pageUrl = mWebServer.setResponse(FAVICON1_PAGE_URL, FAVICON1_PAGE_HTML,
116 CommonResources.getTextHtmlHeaders(true));
118 loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), pageUrl);
120 mContentsClient.mFaviconHelper.waitForCallback(callCount);
121 assertEquals(1, mWebServer.getRequestCount(FAVICON1_URL));
122 Object originalFaviconSource = (new URL(faviconUrl)).getContent();
123 Bitmap originalFavicon = BitmapFactory.decodeStream((InputStream) originalFaviconSource);
124 assertNotNull(originalFavicon);
125 assertNotNull(mContentsClient.mFaviconHelper.mIcon);
126 assertTrue(mContentsClient.mFaviconHelper.mIcon.sameAs(originalFavicon));
128 // Make sure the request counter for favicon is incremented when the page is loaded again
130 loadUrlAsync(mAwContents, pageUrl);
131 mContentsClient.mFaviconHelper.waitForCallback(callCount);
132 assertEquals(2, mWebServer.getRequestCount(FAVICON1_URL));
136 public void testDoNotMakeRequestForFaviconAfter404() throws Throwable {
137 init(new TestAwContentsClientFavicon());
139 mWebServer.setResponseWithNotFoundStatus(FAVICON1_URL);
140 final String pageUrl = mWebServer.setResponse(FAVICON1_PAGE_URL, FAVICON1_PAGE_HTML,
141 CommonResources.getTextHtmlHeaders(true));
143 loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), pageUrl);
144 poll(new Callable<Boolean>() {
146 public Boolean call() throws Exception {
147 return mWebServer.getRequestCount(FAVICON1_URL) == 1;
151 // Make sure the request counter for favicon is not incremented, since we already got 404.
152 loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), pageUrl);
153 // If a request hasn't been done within this time period, we assume it won't be done.
154 Thread.sleep(MAX_REQUEST_WAITING_LIMIT_MS);
155 assertEquals(1, mWebServer.getRequestCount(FAVICON1_URL));
159 public void testReceiveBasicTouchIconLinkRel() throws Throwable {
160 init(new TestAwContentsClientTouchIcon());
161 int callCount = mContentsClient.mFaviconHelper.getCallCount();
163 final String pageUrl = mWebServer.setResponse(TOUCHICON_REL_URL, TOUCHICON_REL_PAGE_HTML,
164 CommonResources.getTextHtmlHeaders(true));
166 loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), pageUrl);
168 mContentsClient.mFaviconHelper.waitForCallback(callCount, 2);
169 HashMap<String, Boolean> touchIcons = mContentsClient.mFaviconHelper.mTouchIcons;
170 assertEquals(2, touchIcons.size());
171 assertFalse(touchIcons.get(mWebServer.getBaseUrl() + TOUCHICON_REL_LINK));
172 assertFalse(touchIcons.get(mWebServer.getBaseUrl() + TOUCHICON_REL_LINK_72));