[Icons NTP] Enable Large Icon URL storage and image fetching (Touch Icons only), behind flag.

This works with crrev.com/1007563004 so URLs for Big Icons (currently only
Apple Touch Icon) are saved into Favicon database, and the icons get fetched
and stored. The feature is hidden behind flag "IconNTP/Enabled". rogerm@ is
working on bounding storage size of large icons.

Also doing some refactoring on FaviconHandler: existing has some ambiguity
on "handler type" and "icon type".

BUG=467712

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

Cr-Commit-Position: refs/heads/master@{#321140}
diff --git a/chrome/browser/favicon/favicon_tab_helper.cc b/chrome/browser/favicon/favicon_tab_helper.cc
index d95ffd1..a6a2d74 100644
--- a/chrome/browser/favicon/favicon_tab_helper.cc
+++ b/chrome/browser/favicon/favicon_tab_helper.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/favicon/favicon_tab_helper.h"
 
+#include "base/metrics/field_trial.h"
+#include "base/strings/string_util.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/favicon/chrome_favicon_client.h"
 #include "chrome/browser/favicon/chrome_favicon_client_factory.h"
@@ -40,6 +42,16 @@
 
 DEFINE_WEB_CONTENTS_USER_DATA_KEY(FaviconTabHelper);
 
+namespace {
+
+// Returns whether icon NTP is enabled.
+bool IsIconNTPEnabled() {
+  return StartsWithASCII(base::FieldTrialList::FindFullName("IconNTP"),
+                         "Enabled", true);
+}
+
+}  // namespace
+
 FaviconTabHelper::FaviconTabHelper(WebContents* web_contents)
     : content::WebContentsObserver(web_contents),
       profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())) {
@@ -56,6 +68,9 @@
   if (chrome::kEnableTouchIcon)
     touch_icon_handler_.reset(new FaviconHandler(
         service, client_, this, FaviconHandler::TOUCH, download_largest_icon));
+  if (IsIconNTPEnabled())
+    large_icon_handler_.reset(new FaviconHandler(
+        service, client_, this, FaviconHandler::LARGE, true));
 }
 
 FaviconTabHelper::~FaviconTabHelper() {
@@ -65,6 +80,8 @@
   favicon_handler_->FetchFavicon(url);
   if (touch_icon_handler_.get())
     touch_icon_handler_->FetchFavicon(url);
+  if (large_icon_handler_.get())
+    large_icon_handler_->FetchFavicon(url);
 }
 
 gfx::Image FaviconTabHelper::GetFavicon() const {
@@ -300,6 +317,8 @@
   favicon_handler_->OnUpdateFaviconURL(favicon_urls);
   if (touch_icon_handler_.get())
     touch_icon_handler_->OnUpdateFaviconURL(favicon_urls);
+  if (large_icon_handler_.get())
+    large_icon_handler_->OnUpdateFaviconURL(favicon_urls);
 }
 
 void FaviconTabHelper::DidDownloadFavicon(
@@ -323,4 +342,8 @@
     touch_icon_handler_->OnDidDownloadFavicon(
         id, image_url, bitmaps, original_bitmap_sizes);
   }
+  if (large_icon_handler_.get()) {
+    large_icon_handler_->OnDidDownloadFavicon(
+        id, image_url, bitmaps, original_bitmap_sizes);
+  }
 }
diff --git a/chrome/browser/favicon/favicon_tab_helper.h b/chrome/browser/favicon/favicon_tab_helper.h
index f3c3cb9..6ee0221 100644
--- a/chrome/browser/favicon/favicon_tab_helper.h
+++ b/chrome/browser/favicon/favicon_tab_helper.h
@@ -136,6 +136,8 @@
   // browser_defaults::kEnableTouchIcon is false.
   scoped_ptr<FaviconHandler> touch_icon_handler_;
 
+  scoped_ptr<FaviconHandler> large_icon_handler_;
+
   ObserverList<FaviconTabHelperObserver> observer_list_;
 
   DISALLOW_COPY_AND_ASSIGN(FaviconTabHelper);
diff --git a/components/favicon/core/browser/favicon_handler.cc b/components/favicon/core/browser/favicon_handler.cc
index 1cff52c..6659779 100644
--- a/components/favicon/core/browser/favicon_handler.cc
+++ b/components/favicon/core/browser/favicon_handler.cc
@@ -202,14 +202,12 @@
 FaviconHandler::FaviconHandler(FaviconService* service,
                                FaviconClient* client,
                                FaviconDriver* driver,
-                               Type icon_type,
+                               Type handler_type,
                                bool download_largest_icon)
     : got_favicon_from_history_(false),
       favicon_expired_or_incomplete_(false),
-      icon_types_(icon_type == FAVICON
-                      ? favicon_base::FAVICON
-                      : favicon_base::TOUCH_ICON |
-                            favicon_base::TOUCH_PRECOMPOSED_ICON),
+      handler_type_(handler_type),
+      icon_types_(FaviconHandler::GetIconTypesFromHandlerType(handler_type)),
       download_largest_icon_(download_largest_icon),
       service_(service),
       client_(client),
@@ -220,6 +218,21 @@
 FaviconHandler::~FaviconHandler() {
 }
 
+// static
+int FaviconHandler::GetIconTypesFromHandlerType(
+    FaviconHandler::Type handler_type) {
+  switch (handler_type) {
+    case FAVICON:
+      return favicon_base::FAVICON;
+    case TOUCH:  // Falls through.
+    case LARGE:
+      return favicon_base::TOUCH_ICON | favicon_base::TOUCH_PRECOMPOSED_ICON;
+    default:
+      NOTREACHED();
+  }
+  return 0;
+}
+
 void FaviconHandler::FetchFavicon(const GURL& url) {
   cancelable_task_tracker_.TryCancelAll();
 
@@ -502,6 +515,7 @@
                                         const GURL& icon_url,
                                         favicon_base::IconType icon_type,
                                         const gfx::Image& image) {
+  // TODO(huangs): Get the following to garbage collect if handler_type_ == ALL.
   if (service_) {
     service_->SetFavicons(page_url, icon_url, icon_type, image);
   }
@@ -545,7 +559,7 @@
       preferred_icon_size(), favicon_bitmap_results);
   bool has_valid_result = HasValidResult(favicon_bitmap_results);
 
-  if (has_results && icon_types_ == favicon_base::FAVICON &&
+  if (has_results && handler_type_ == FAVICON &&
       !download_largest_icon_ && !driver_->GetActiveFaviconValidity() &&
       (!current_candidate() ||
        DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results))) {
@@ -583,8 +597,7 @@
   // else we haven't got the icon url. When we get it we'll ask the
   // renderer to download the icon.
 
-  if (has_valid_result &&
-      (icon_types_ != favicon_base::FAVICON || download_largest_icon_))
+  if (has_valid_result && (handler_type_ != FAVICON || download_largest_icon_))
     NotifyFaviconAvailable(favicon_bitmap_results, false);
 }
 
@@ -628,8 +641,7 @@
       preferred_icon_size(), favicon_bitmap_results);
   bool has_valid_result = HasValidResult(favicon_bitmap_results);
 
-  if (has_results && icon_types_ == favicon_base::FAVICON &&
-      !download_largest_icon_) {
+  if (has_results && handler_type_ == FAVICON && !download_largest_icon_) {
     if (has_valid_result) {
       // There is a favicon, set it now. If expired we'll download the current
       // one again, but at least the user will get some icon instead of the
@@ -654,7 +666,7 @@
   history_results_ = favicon_bitmap_results;
 
   if (has_valid_result &&
-      (icon_types_ != favicon_base::FAVICON || download_largest_icon_)) {
+      (handler_type_ != FAVICON || download_largest_icon_)) {
     NotifyFaviconAvailable(favicon_bitmap_results, false);
   }
 }
diff --git a/components/favicon/core/browser/favicon_handler.h b/components/favicon/core/browser/favicon_handler.h
index 5d890c0e9..90cd152f1 100644
--- a/components/favicon/core/browser/favicon_handler.h
+++ b/components/favicon/core/browser/favicon_handler.h
@@ -76,15 +76,18 @@
 
 class FaviconHandler {
  public:
-  enum Type { FAVICON, TOUCH };
+  enum Type { FAVICON, TOUCH, LARGE };
 
   FaviconHandler(FaviconService* service,
                  FaviconClient* client,
                  FaviconDriver* driver,
-                 Type icon_type,
+                 Type handler_type,
                  bool download_largest_icon);
   virtual ~FaviconHandler();
 
+  // Returns the bit mask of favicon_base::IconType based on the handler's type.
+  static int GetIconTypesFromHandlerType(Type icon_type);
+
   // Initiates loading the favicon for the specified url.
   void FetchFavicon(const GURL& url);
 
@@ -92,7 +95,7 @@
   // PrerenderContents. Collects the |image_urls| list.
   void OnUpdateFaviconURL(const std::vector<favicon::FaviconURL>& candidates);
 
-  // Processes the current image_irls_ entry, requesting the image from the
+  // Processes the current image_urls_ entry, requesting the image from the
   // history / download service.
   void ProcessCurrentUrl();
 
@@ -245,7 +248,7 @@
   int preferred_icon_size() const {
     if (download_largest_icon_)
       return 0;
-    return icon_types_ == favicon_base::FAVICON ? gfx::kFaviconSize : 0;
+    return handler_type_ == FAVICON ? gfx::kFaviconSize : 0;
   }
 
   // Sorts the entries in |image_urls_| by icon size in descending order.
@@ -275,6 +278,9 @@
   typedef std::map<int, DownloadRequest> DownloadRequests;
   DownloadRequests download_requests_;
 
+  // The type of the current handler.
+  const Type handler_type_;
+
   // The combination of the supported icon types.
   const int icon_types_;