Home | History | Annotate | Download | only in test
      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.
      4 
      5 package org.chromium.android_webview.test;
      6 
      7 import android.graphics.Bitmap;
      8 import android.graphics.BitmapFactory;
      9 import android.test.suitebuilder.annotation.SmallTest;
     10 
     11 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
     12 
     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;
     17 
     18 import java.io.InputStream;
     19 import java.net.URL;
     20 import java.util.HashMap;
     21 import java.util.concurrent.Callable;
     22 
     23 /**
     24  * Tests for the Favicon and TouchIcon related APIs.
     25  */
     26 public class AwContentsClientFaviconTest extends AwTestBase {
     27 
     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 + "\" />",
     33                     "Body");
     34 
     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
     43                     + "\" />",
     44                     "Body");
     45 
     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);
     48 
     49     private static class FaviconHelper extends CallbackHelper {
     50         private Bitmap mIcon;
     51         private HashMap<String, Boolean> mTouchIcons = new HashMap<String, Boolean>();
     52 
     53         public void notifyFavicon(Bitmap icon) {
     54             mIcon = icon;
     55             super.notifyCalled();
     56         }
     57 
     58         public void notifyTouchIcon(String url, boolean precomposed) {
     59             mTouchIcons.put(url, precomposed);
     60             super.notifyCalled();
     61         }
     62     }
     63 
     64     private static class TestAwContentsClientBase
     65             extends org.chromium.android_webview.test.TestAwContentsClient {
     66         FaviconHelper mFaviconHelper = new FaviconHelper();
     67     }
     68 
     69     private static class TestAwContentsClientFavicon extends TestAwContentsClientBase {
     70         @Override
     71         public void onReceivedIcon(Bitmap bitmap) {
     72             // We don't inform the API client about the URL of the icon.
     73             mFaviconHelper.notifyFavicon(bitmap);
     74         }
     75     }
     76 
     77     private static class TestAwContentsClientTouchIcon extends TestAwContentsClientBase {
     78         @Override
     79         public void onReceivedTouchIconUrl(String url, boolean precomposed) {
     80             mFaviconHelper.notifyTouchIcon(url, precomposed);
     81         }
     82     }
     83 
     84     private TestAwContentsClientBase mContentsClient;
     85     private AwContents mAwContents;
     86     private TestWebServer mWebServer;
     87 
     88     @Override
     89     protected void setUp() throws Exception {
     90         super.setUp();
     91         AwContents.setShouldDownloadFavicons();
     92         mWebServer = new TestWebServer(false);
     93     }
     94 
     95     private void init(TestAwContentsClientBase contentsClient) throws Exception {
     96         mContentsClient = contentsClient;
     97         AwTestContainerView testContainerView =
     98                 createAwTestContainerViewOnMainSync(mContentsClient);
     99         mAwContents = testContainerView.getAwContents();
    100     }
    101 
    102     @Override
    103     protected void tearDown() throws Exception {
    104         if (mWebServer != null) mWebServer.shutdown();
    105         super.tearDown();
    106     }
    107 
    108     @SmallTest
    109     public void testReceiveBasicFavicon() throws Throwable {
    110         init(new TestAwContentsClientFavicon());
    111         int callCount = mContentsClient.mFaviconHelper.getCallCount();
    112 
    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));
    117 
    118         loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), pageUrl);
    119 
    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));
    127 
    128         // Make sure the request counter for favicon is incremented when the page is loaded again
    129         // successfully.
    130         loadUrlAsync(mAwContents, pageUrl);
    131         mContentsClient.mFaviconHelper.waitForCallback(callCount);
    132         assertEquals(2, mWebServer.getRequestCount(FAVICON1_URL));
    133     }
    134 
    135     @SmallTest
    136     public void testDoNotMakeRequestForFaviconAfter404() throws Throwable {
    137         init(new TestAwContentsClientFavicon());
    138 
    139         mWebServer.setResponseWithNotFoundStatus(FAVICON1_URL);
    140         final String pageUrl = mWebServer.setResponse(FAVICON1_PAGE_URL, FAVICON1_PAGE_HTML,
    141             CommonResources.getTextHtmlHeaders(true));
    142 
    143         loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), pageUrl);
    144         poll(new Callable<Boolean>() {
    145             @Override
    146             public Boolean call() throws Exception {
    147                 return mWebServer.getRequestCount(FAVICON1_URL) == 1;
    148             }
    149         });
    150 
    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));
    156     }
    157 
    158     @SmallTest
    159     public void testReceiveBasicTouchIconLinkRel() throws Throwable {
    160         init(new TestAwContentsClientTouchIcon());
    161         int callCount = mContentsClient.mFaviconHelper.getCallCount();
    162 
    163         final String pageUrl = mWebServer.setResponse(TOUCHICON_REL_URL, TOUCHICON_REL_PAGE_HTML,
    164             CommonResources.getTextHtmlHeaders(true));
    165 
    166         loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), pageUrl);
    167 
    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));
    173     }
    174 }
    175