Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(496)

Unified Diff: chrome/browser/favicon_tab_helper.cc

Issue 6814029: Revert 80519 - Move favicon from TabContents to TabContentsWrapper. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/favicon_tab_helper.h ('k') | chrome/browser/prerender/prerender_manager.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/favicon_tab_helper.cc
===================================================================
--- chrome/browser/favicon_tab_helper.cc (revision 80859)
+++ chrome/browser/favicon_tab_helper.cc (working copy)
@@ -1,398 +0,0 @@
-// Copyright (c) 2011 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.
-
-#include "chrome/browser/favicon_tab_helper.h"
-
-#include "build/build_config.h"
-
-#include <vector>
-
-#include "base/callback.h"
-#include "base/memory/ref_counted_memory.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/common/render_messages.h"
-#include "content/browser/renderer_host/render_view_host.h"
-#include "content/browser/tab_contents/navigation_controller.h"
-#include "content/browser/tab_contents/navigation_entry.h"
-#include "content/browser/tab_contents/tab_contents_delegate.h"
-#include "content/browser/tab_contents/tab_contents.h"
-#include "content/browser/webui/web_ui.h"
-#include "skia/ext/image_operations.h"
-#include "ui/gfx/codec/png_codec.h"
-#include "ui/gfx/favicon_size.h"
-
-FaviconTabHelper::FaviconTabHelper(TabContents* tab_contents)
- : TabContentsObserver(tab_contents),
- got_favicon_url_(false),
- got_favicon_from_history_(false),
- favicon_expired_(false) {
-}
-
-FaviconTabHelper::~FaviconTabHelper() {
- SkBitmap empty_image;
-
- // Call pending download callbacks with error to allow caller to clean up.
- for (DownloadRequests::iterator i = download_requests_.begin();
- i != download_requests_.end(); ++i) {
- if (i->second.callback) {
- i->second.callback->Run(i->first, true, empty_image);
- }
- }
-}
-
-SkBitmap FaviconTabHelper::GetFavicon() const {
- // Like GetTitle(), we also want to use the favicon for the last committed
- // entry rather than a pending navigation entry.
- NavigationEntry* entry = tab_contents()->controller().GetTransientEntry();
- if (entry)
- return entry->favicon().bitmap();
-
- entry = tab_contents()->controller().GetLastCommittedEntry();
- if (entry)
- return entry->favicon().bitmap();
- return SkBitmap();
-}
-
-bool FaviconTabHelper::FaviconIsValid() const {
- const NavigationController& controller = tab_contents()->controller();
- NavigationEntry* entry = controller.GetTransientEntry();
- if (entry)
- return entry->favicon().is_valid();
-
- entry = controller.GetLastCommittedEntry();
- if (entry)
- return entry->favicon().is_valid();
-
- return false;
-}
-
-bool FaviconTabHelper::ShouldDisplayFavicon() {
- // Always display a throbber during pending loads.
- const NavigationController& controller = tab_contents()->controller();
- if (controller.GetLastCommittedEntry() && controller.pending_entry())
- return true;
-
- WebUI* web_ui = tab_contents()->GetWebUIForCurrentState();
- if (web_ui)
- return !web_ui->hide_favicon();
- return true;
-}
-
-void FaviconTabHelper::FetchFavicon(const GURL& url) {
- cancelable_consumer_.CancelAllRequests();
-
- url_ = url;
-
- favicon_expired_ = got_favicon_from_history_ = got_favicon_url_ = false;
-
- // Request the favicon from the history service. In parallel to this the
- // renderer is going to notify us (well TabContents) when the favicon url is
- // available.
- if (GetFaviconService()) {
- GetFaviconService()->GetFaviconForURL(url_, history::FAVICON,
- &cancelable_consumer_,
- NewCallback(this, &FaviconTabHelper::OnFaviconDataForInitialURL));
- }
-}
-
-int FaviconTabHelper::DownloadImage(const GURL& image_url,
- int image_size,
- ImageDownloadCallback* callback) {
- DCHECK(callback); // Must provide a callback.
- return ScheduleDownload(GURL(), image_url, image_size, callback);
-}
-
-FaviconService* FaviconTabHelper::GetFaviconService() {
- return tab_contents()->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS);
-}
-
-void FaviconTabHelper::SetFavicon(
- const GURL& url,
- const GURL& image_url,
- const SkBitmap& image) {
- const SkBitmap& sized_image =
- (image.width() == kFaviconSize && image.height() == kFaviconSize)
- ? image : ConvertToFaviconSize(image);
-
- if (GetFaviconService() && ShouldSaveFavicon(url)) {
- std::vector<unsigned char> image_data;
- gfx::PNGCodec::EncodeBGRASkBitmap(sized_image, false, &image_data);
- GetFaviconService()->SetFavicon(url, image_url, image_data,
- history::FAVICON);
- }
-
- if (url == url_) {
- NavigationEntry* entry = GetEntry();
- if (entry)
- UpdateFavicon(entry, sized_image);
- }
-}
-
-void FaviconTabHelper::SaveFavicon() {
- NavigationEntry* entry = tab_contents()->controller().GetActiveEntry();
- if (!entry || entry->url().is_empty())
- return;
-
- // Make sure the page is in history, otherwise adding the favicon does
- // nothing.
- HistoryService* history =
- tab_contents()->profile()->GetOriginalProfile()->GetHistoryService(
- Profile::IMPLICIT_ACCESS);
- if (!history)
- return;
- history->AddPageNoVisitForBookmark(entry->url());
-
- FaviconService* service = tab_contents()->profile()->
- GetOriginalProfile()->GetFaviconService(Profile::IMPLICIT_ACCESS);
- if (!service)
- return;
- const NavigationEntry::FaviconStatus& favicon(entry->favicon());
- if (!favicon.is_valid() || favicon.url().is_empty() ||
- favicon.bitmap().empty()) {
- return;
- }
- std::vector<unsigned char> image_data;
- gfx::PNGCodec::EncodeBGRASkBitmap(favicon.bitmap(), false, &image_data);
- service->SetFavicon(
- entry->url(), favicon.url(), image_data, history::FAVICON);
-}
-
-void FaviconTabHelper::UpdateFavicon(NavigationEntry* entry,
- scoped_refptr<RefCountedMemory> data) {
- SkBitmap image;
- gfx::PNGCodec::Decode(data->front(), data->size(), &image);
- UpdateFavicon(entry, image);
-}
-
-void FaviconTabHelper::UpdateFavicon(NavigationEntry* entry,
- const SkBitmap& image) {
- // No matter what happens, we need to mark the favicon as being set.
- entry->favicon().set_is_valid(true);
-
- if (image.empty())
- return;
-
- entry->favicon().set_bitmap(image);
- tab_contents()->NotifyNavigationStateChanged(TabContents::INVALIDATE_TAB);
-}
-
-void FaviconTabHelper::OnUpdateFaviconURL(int32 page_id, const GURL& icon_url) {
- // TODO(davemoore) Should clear on empty url. Currently we ignore it.
- // This appears to be what FF does as well.
- if (icon_url.is_empty())
- return;
-
- NavigationEntry* entry = GetEntry();
- if (!entry)
- return;
-
- got_favicon_url_ = true;
-
- if (!GetFaviconService())
- return;
-
- if (!favicon_expired_ && entry->favicon().is_valid() &&
- entry->favicon().url() == icon_url) {
- // We already have the icon, no need to proceed.
- return;
- }
-
- entry->favicon().set_url(icon_url);
-
- if (got_favicon_from_history_)
- DownloadFaviconOrAskHistory(entry);
-}
-
-void FaviconTabHelper::NavigateToPendingEntry(
- const GURL& url,
- NavigationController::ReloadType reload_type) {
- if (reload_type != NavigationController::NO_RELOAD &&
- !tab_contents()->profile()->IsOffTheRecord()) {
- FaviconService* favicon_service =
- tab_contents()->profile()->GetFaviconService(Profile::IMPLICIT_ACCESS);
- if (favicon_service)
- favicon_service->SetFaviconOutOfDateForPage(url);
- }
-}
-
-void FaviconTabHelper::DidNavigateMainFramePostCommit(
- const NavigationController::LoadCommittedDetails& details,
- const ViewHostMsg_FrameNavigate_Params& /*params*/) {
- // Get the favicon, either from history or request it from the net.
- FetchFavicon(details.entry->url());
-}
-
-bool FaviconTabHelper::OnMessageReceived(const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(FaviconTabHelper, message)
- IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateFaviconURL, OnUpdateFaviconURL)
- IPC_MESSAGE_HANDLER(ViewHostMsg_DidDownloadFavicon, OnDidDownloadFavicon)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-void FaviconTabHelper::OnDidDownloadFavicon(int id,
- const GURL& image_url,
- bool errored,
- const SkBitmap& image) {
- DownloadRequests::iterator i = download_requests_.find(id);
- if (i == download_requests_.end()) {
- // Currently TabContents notifies us of ANY downloads so that it is
- // possible to get here.
- return;
- }
-
- if (i->second.callback) {
- i->second.callback->Run(id, errored, image);
- } else if (!errored) {
- SetFavicon(i->second.url, image_url, image);
- }
-
- download_requests_.erase(i);
-}
-
-NavigationEntry* FaviconTabHelper::GetEntry() {
- NavigationEntry* entry = tab_contents()->controller().GetActiveEntry();
- if (entry && entry->url() == url_ &&
- tab_contents()->IsActiveEntry(entry->page_id())) {
- return entry;
- }
- // If the URL has changed out from under us (as will happen with redirects)
- // return NULL.
- return NULL;
-}
-
-void FaviconTabHelper::OnFaviconDataForInitialURL(
- FaviconService::Handle handle,
- history::FaviconData favicon) {
- NavigationEntry* entry = GetEntry();
- if (!entry)
- return;
-
- got_favicon_from_history_ = true;
-
- favicon_expired_ = (favicon.known_icon && favicon.expired);
-
- if (favicon.known_icon && !entry->favicon().is_valid() &&
- (!got_favicon_url_ || entry->favicon().url() == favicon.icon_url)) {
- // The db knows the favicon (although it may be out of date) and the entry
- // doesn't have an icon. Set the favicon now, and if the favicon turns out
- // to be expired (or the wrong url) we'll fetch later on. This way the
- // user doesn't see a flash of the default favicon.
- entry->favicon().set_url(favicon.icon_url);
- if (favicon.is_valid())
- UpdateFavicon(entry, favicon.image_data);
- entry->favicon().set_is_valid(true);
- }
-
- if (favicon.known_icon && !favicon.expired) {
- if (got_favicon_url_ && entry->favicon().url() != favicon.icon_url) {
- // Mapping in the database is wrong. DownloadFaviconOrAskHistory will
- // update the mapping for this url and download the favicon if we don't
- // already have it.
- DownloadFaviconOrAskHistory(entry);
- }
- } else if (got_favicon_url_) {
- // We know the official url for the favicon, by either don't have the
- // favicon or its expired. Continue on to DownloadFaviconOrAskHistory to
- // either download or check history again.
- DownloadFaviconOrAskHistory(entry);
- }
- // else we haven't got the icon url. When we get it we'll ask the
- // renderer to download the icon.
-}
-
-void FaviconTabHelper::DownloadFaviconOrAskHistory(NavigationEntry* entry) {
- DCHECK(entry); // We should only get here if entry is valid.
- if (favicon_expired_) {
- // We have the mapping, but the favicon is out of date. Download it now.
- ScheduleDownload(entry->url(), entry->favicon().url(), kFaviconSize, NULL);
- } else if (GetFaviconService()) {
- // We don't know the favicon, but we may have previously downloaded the
- // favicon for another page that shares the same favicon. Ask for the
- // favicon given the favicon URL.
- if (tab_contents()->profile()->IsOffTheRecord()) {
- GetFaviconService()->GetFavicon(
- entry->favicon().url(),
- history::FAVICON,
- &cancelable_consumer_,
- NewCallback(this, &FaviconTabHelper::OnFaviconData));
- } else {
- // Ask the history service for the icon. This does two things:
- // 1. Attempts to fetch the favicon data from the database.
- // 2. If the favicon exists in the database, this updates the database to
- // include the mapping between the page url and the favicon url.
- // This is asynchronous. The history service will call back when done.
- // Issue the request and associate the current page ID with it.
- GetFaviconService()->UpdateFaviconMappingAndFetch(
- entry->url(),
- entry->favicon().url(),
- history::FAVICON,
- &cancelable_consumer_,
- NewCallback(this, &FaviconTabHelper::OnFaviconData));
- }
- }
-}
-
-void FaviconTabHelper::OnFaviconData(
- FaviconService::Handle handle,
- history::FaviconData favicon) {
- NavigationEntry* entry = GetEntry();
- if (!entry)
- return;
-
- // No need to update the favicon url. By the time we get here
- // UpdateFaviconURL will have set the favicon url.
-
- if (favicon.is_valid()) {
- // 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
- // default and most likely the current one is fine anyway.
- UpdateFavicon(entry, favicon.image_data);
- }
-
- if (!favicon.known_icon || favicon.expired) {
- // We don't know the favicon, or it is out of date. Request the current one.
- ScheduleDownload(entry->url(), entry->favicon().url(), kFaviconSize, NULL);
- }
-}
-
-int FaviconTabHelper::ScheduleDownload(const GURL& url,
- const GURL& image_url,
- int image_size,
- ImageDownloadCallback* callback) {
- const int download_id = tab_contents()->render_view_host()->DownloadFavicon(
- image_url, image_size);
-
- if (download_id) {
- // Download ids should be unique.
- DCHECK(download_requests_.find(download_id) == download_requests_.end());
- download_requests_[download_id] = DownloadRequest(url, image_url, callback);
- }
-
- return download_id;
-}
-
-SkBitmap FaviconTabHelper::ConvertToFaviconSize(const SkBitmap& image) {
- int width = image.width();
- int height = image.height();
- if (width > 0 && height > 0) {
- calc_favicon_target_size(&width, &height);
- return skia::ImageOperations::Resize(
- image, skia::ImageOperations::RESIZE_LANCZOS3,
- width, height);
- }
- return image;
-}
-
-bool FaviconTabHelper::ShouldSaveFavicon(const GURL& url) {
- if (!tab_contents()->profile()->IsOffTheRecord())
- return true;
-
- // Otherwise store the favicon if the page is bookmarked.
- BookmarkModel* bookmark_model = tab_contents()->profile()->GetBookmarkModel();
- return bookmark_model && bookmark_model->IsBookmarked(url);
-}
« no previous file with comments | « chrome/browser/favicon_tab_helper.h ('k') | chrome/browser/prerender/prerender_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698