C++程序  |  276行  |  11.86 KB

// Copyright (c) 2012 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.

#ifndef CHROME_BROWSER_FAVICON_FAVICON_SERVICE_H_
#define CHROME_BROWSER_FAVICON_FAVICON_SERVICE_H_

#include <vector>

#include "base/callback.h"
#include "base/containers/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "chrome/browser/common/cancelable_request.h"
#include "chrome/common/cancelable_task_tracker.h"
#include "chrome/common/favicon/favicon_types.h"
#include "chrome/common/ref_counted_util.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
#include "ui/base/layout.h"

class GURL;
class HistoryService;
struct ImportedFaviconUsage;
class Profile;

namespace chrome {
struct FaviconImageResult;
}

// The favicon service provides methods to access favicons. It calls the history
// backend behind the scenes.
//
// This service is thread safe. Each request callback is invoked in the
// thread that made the request.
class FaviconService : public CancelableRequestProvider,
                       public BrowserContextKeyedService {
 public:
  explicit FaviconService(Profile* profile);

  virtual ~FaviconService();

  // Auxiliary argument structure for requesting favicons for URLs.
  struct FaviconForURLParams {
    FaviconForURLParams(const GURL& page_url,
                        int icon_types,
                        int desired_size_in_dip)
        : page_url(page_url),
          icon_types(icon_types),
          desired_size_in_dip(desired_size_in_dip) {}

    GURL page_url;
    int icon_types;
    int desired_size_in_dip;
  };

  // Callback for GetFaviconImage() and GetFaviconImageForURL().
  // |FaviconImageResult::image| is constructed from the bitmaps for the
  // passed in URL and icon types which most which closely match the passed in
  // |desired_size_in_dip| at the scale factors supported by the current
  // platform (eg MacOS) in addition to 1x.
  // |FaviconImageResult::icon_url| is the favicon that the favicon bitmaps in
  // |image| originate from.
  // TODO(pkotwicz): Enable constructing |image| from bitmaps from several
  // icon URLs.
  typedef base::Callback<void(const chrome::FaviconImageResult&)>
      FaviconImageCallback;

  // Callback for GetRawFavicon(), GetRawFaviconForURL() and
  // GetLargestRawFavicon().
  // See function for details on value.
  typedef base::Callback<void(const chrome::FaviconBitmapResult&)>
      FaviconRawCallback;

  // Callback for GetFavicon() and GetFaviconForURL().
  //
  // The first argument is the set of bitmaps for the passed in URL and
  // icon types whose pixel sizes best match the passed in
  // |desired_size_in_dip| at the scale factors supported by the current
  // platform (eg MacOS) in addition to 1x. The vector has at most one result
  // for each of the scale factors. There are less entries if a single result
  // is the best bitmap to use for several scale factors.
  typedef base::Callback<void(const std::vector<chrome::FaviconBitmapResult>&)>
      FaviconResultsCallback;

  // We usually pass parameters with pointer to avoid copy. This function is a
  // helper to run FaviconResultsCallback with pointer parameters.
  static void FaviconResultsCallbackRunner(
      const FaviconResultsCallback& callback,
      const std::vector<chrome::FaviconBitmapResult>* results);

  // Requests the favicon at |icon_url| of |icon_type| whose size most closely
  // matches |desired_size_in_dip|. If |desired_size_in_dip| is 0, the largest
  // favicon bitmap at |icon_url| is returned. |consumer| is notified when the
  // bits have been fetched. |icon_url| is the URL of the icon itself, e.g.
  // <http://www.google.com/favicon.ico>.
  // Each of the three methods below differs in the format of the callback and
  // the requested scale factors. All of the scale factors supported by the
  // current platform (eg MacOS) are requested for GetFaviconImage().
  CancelableTaskTracker::TaskId GetFaviconImage(
      const GURL& icon_url,
      chrome::IconType icon_type,
      int desired_size_in_dip,
      const FaviconImageCallback& callback,
      CancelableTaskTracker* tracker);

  CancelableTaskTracker::TaskId GetRawFavicon(
      const GURL& icon_url,
      chrome::IconType icon_type,
      int desired_size_in_dip,
      ui::ScaleFactor desired_scale_factor,
      const FaviconRawCallback& callback,
      CancelableTaskTracker* tracker);

  CancelableTaskTracker::TaskId GetFavicon(
      const GURL& icon_url,
      chrome::IconType icon_type,
      int desired_size_in_dip,
      const FaviconResultsCallback& callback,
      CancelableTaskTracker* tracker);

  // Set the favicon mappings to |page_url| for |icon_types| in the history
  // database.
  // Sample |icon_urls|:
  //  { ICON_URL1 -> TOUCH_ICON, known to the database,
  //    ICON_URL2 -> TOUCH_ICON, not known to the database,
  //    ICON_URL3 -> TOUCH_PRECOMPOSED_ICON, known to the database }
  // The new mappings are computed from |icon_urls| with these rules:
  // 1) Any urls in |icon_urls| which are not already known to the database are
  //    rejected.
  //    Sample new mappings to |page_url|: { ICON_URL1, ICON_URL3 }
  // 2) If |icon_types| has multiple types, the mappings are only set for the
  //    largest icon type.
  //    Sample new mappings to |page_url|: { ICON_URL3 }
  // |icon_types| can only have multiple IconTypes if
  // |icon_types| == TOUCH_ICON | TOUCH_PRECOMPOSED_ICON.
  // The favicon bitmaps which most closely match |desired_size_in_dip|
  // at the scale factors supported by the current platform (eg MacOS) in
  // addition to 1x from the favicons which were just mapped to |page_url| are
  // returned. If |desired_size_in_dip| is 0, the largest favicon bitmap is
  // returned.
  CancelableTaskTracker::TaskId UpdateFaviconMappingsAndFetch(
      const GURL& page_url,
      const std::vector<GURL>& icon_urls,
      int icon_types,
      int desired_size_in_dip,
      const FaviconResultsCallback& callback,
      CancelableTaskTracker* tracker);

  // Requests the favicons of any of |icon_types| whose pixel sizes most
  // closely match |desired_size_in_dip| and desired scale factors for a web
  // page URL. If |desired_size_in_dip| is 0, the largest favicon for the web
  // page URL is returned. |callback| is run when the bits have been fetched.
  // |icon_types| can be any combination of IconType value, but only one icon
  // will be returned in the priority of TOUCH_PRECOMPOSED_ICON, TOUCH_ICON and
  // FAVICON. Each of the three methods below differs in the format of the
  // callback and the requested scale factors. All of the scale factors
  // supported by the current platform (eg MacOS) are requested for
  // GetFaviconImageForURL().
  // Note. |callback| is always run asynchronously.
  CancelableTaskTracker::TaskId GetFaviconImageForURL(
      const FaviconForURLParams& params,
      const FaviconImageCallback& callback,
      CancelableTaskTracker* tracker);

  CancelableTaskTracker::TaskId GetRawFaviconForURL(
      const FaviconForURLParams& params,
      ui::ScaleFactor desired_scale_factor,
      const FaviconRawCallback& callback,
      CancelableTaskTracker* tracker);

  // See HistoryService::GetLargestFaviconForURL().
  CancelableTaskTracker::TaskId GetLargestRawFaviconForURL(
      Profile* profile,
      const GURL& page_url,
      const std::vector<int>& icon_types,
      int minimum_size_in_pixels,
      const FaviconRawCallback& callback,
      CancelableTaskTracker* tracker);

  CancelableTaskTracker::TaskId GetFaviconForURL(
      const FaviconForURLParams& params,
      const FaviconResultsCallback& callback,
      CancelableTaskTracker* tracker);

  // Used to request a bitmap for the favicon with |favicon_id| which is not
  // resized from the size it is stored at in the database. If there are
  // multiple favicon bitmaps for |favicon_id|, the largest favicon bitmap is
  // returned.
  CancelableTaskTracker::TaskId GetLargestRawFaviconForID(
      chrome::FaviconID favicon_id,
      const FaviconRawCallback& callback,
      CancelableTaskTracker* tracker);

  // Marks all types of favicon for the page as being out of date.
  void SetFaviconOutOfDateForPage(const GURL& page_url);

  // Clones all icons from an existing page. This associates the icons from
  // |old_page_url| with |new_page_url|, provided |new_page_url| has no
  // recorded associations to any other icons.
  // Needed if you want to declare favicons (tentatively) in advance, before a
  // page is ever visited.
  void CloneFavicon(const GURL& old_page_url, const GURL& new_page_url);

  // Allows the importer to set many favicons for many pages at once. The pages
  // must exist, any favicon sets for unknown pages will be discarded. Existing
  // favicons will not be overwritten.
  void SetImportedFavicons(
      const std::vector<ImportedFaviconUsage>& favicon_usage);

  // Set the favicon for |page_url| for |icon_type| in the thumbnail database.
  // Unlike SetFavicons(), this method will not delete preexisting bitmap data
  // which is associated to |page_url| if at all possible. Use this method if
  // the favicon bitmaps for any of ui::GetSupportedScaleFactors() are not
  // known.
  void MergeFavicon(const GURL& page_url,
                    const GURL& icon_url,
                    chrome::IconType icon_type,
                    scoped_refptr<base::RefCountedMemory> bitmap_data,
                    const gfx::Size& pixel_size);

  // Set the favicon for |page_url| for |icon_type| in the thumbnail database.
  // |icon_url| is the single favicon to map to |page_url|. Mappings from
  // |page_url| to favicons at different icon URLs will be deleted.
  // A favicon bitmap is added for each image rep in |image|. Any preexisting
  // bitmap data for |icon_url| is deleted. It is important that |image|
  // contains image reps for all of ui::GetSupportedScaleFactors(). Use
  // MergeFavicon() if it does not.
  // TODO(pkotwicz): Save unresized favicon bitmaps to the database.
  // TODO(pkotwicz): Support adding favicons for multiple icon URLs to the
  // thumbnail database.
  void SetFavicons(const GURL& page_url,
                   const GURL& icon_url,
                   chrome::IconType icon_type,
                   const gfx::Image& image);

  // Avoid repeated requests to download missing favicon.
  void UnableToDownloadFavicon(const GURL& icon_url);
  bool WasUnableToDownloadFavicon(const GURL& icon_url) const;
  void ClearUnableToDownloadFavicons();

 private:
  typedef uint32 MissingFaviconURLHash;
  base::hash_set<MissingFaviconURLHash> missing_favicon_urls_;
  HistoryService* history_service_;
  Profile* profile_;

  // Helper function for GetFaviconImageForURL(), GetRawFaviconForURL() and
  // GetFaviconForURL().
  CancelableTaskTracker::TaskId GetFaviconForURLImpl(
      const FaviconForURLParams& params,
      const std::vector<ui::ScaleFactor>& desired_scale_factors,
      const FaviconResultsCallback& callback,
      CancelableTaskTracker* tracker);

  // Intermediate callback for GetFaviconImage() and GetFaviconImageForURL()
  // so that history service can deal solely with FaviconResultsCallback.
  // Builds chrome::FaviconImageResult from |favicon_bitmap_results| and runs
  // |callback|.
  void RunFaviconImageCallbackWithBitmapResults(
      const FaviconImageCallback& callback,
      int desired_size_in_dip,
      const std::vector<chrome::FaviconBitmapResult>& favicon_bitmap_results);

  // Intermediate callback for GetRawFavicon() and GetRawFaviconForURL()
  // so that history service can deal solely with FaviconResultsCallback.
  // Resizes chrome::FaviconBitmapResult if necessary and runs |callback|.
  void RunFaviconRawCallbackWithBitmapResults(
      const FaviconRawCallback& callback,
      int desired_size_in_dip,
      ui::ScaleFactor desired_scale_factor,
      const std::vector<chrome::FaviconBitmapResult>& favicon_bitmap_results);

  DISALLOW_COPY_AND_ASSIGN(FaviconService);
};

#endif  // CHROME_BROWSER_FAVICON_FAVICON_SERVICE_H_