13f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/top_sites.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <algorithm> 8513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include <set> 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/command_line.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/md5.h" 133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_util.h" 143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/values.h" 16513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/history/history_backend.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/history_notifications.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/page_usage_data.h" 19513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/history/top_sites_backend.h" 20513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/history/top_sites_cache.h" 213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h" 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/prefs/scoped_user_pref_update.h" 2321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/most_visited_handler.h" 253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/chrome_switches.h" 263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/pref_names.h" 273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/thumbnail_score.h" 28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_controller.h" 30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_entry.h" 31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h" 323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "grit/chromium_strings.h" 333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "grit/generated_resources.h" 343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "grit/locale_settings.h" 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/skia/include/core/SkBitmap.h" 3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/codec/jpeg_codec.h" 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace history { 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// How many top sites to store in the cache. 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const size_t kTopSitesNumber = 20; 43513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 44513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Max number of temporary images we'll cache. See comment above 45513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// temp_images_ for details. 46513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstatic const size_t kMaxTempTopImages = 8; 47513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const size_t kTopSitesShown = 8; 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kDaysOfHistory = 90; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Time from startup to first HistoryService query. 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int64 kUpdateIntervalSecs = 15; 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Intervals between requests to HistoryService. 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int64 kMinUpdateIntervalMinutes = 1; 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int64 kMaxUpdateIntervalMinutes = 60; 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// IDs of the sites we force into top sites. 57513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstatic const int kPrepopulatePageIDs[] = 58513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch { IDS_CHROME_WELCOME_URL, IDS_THEMES_GALLERY_URL }; 59513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 60513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Favicons of the sites we force into top sites. 61513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstatic const char kPrepopulateFaviconURLs[][54] = 62513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch { "chrome://theme/IDR_NEWTAB_CHROME_WELCOME_PAGE_FAVICON", 63513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "chrome://theme/IDR_NEWTAB_THEMES_GALLERY_FAVICON" }; 64513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 65513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstatic const int kPrepopulateTitleIDs[] = 66513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch { IDS_NEW_TAB_CHROME_WELCOME_PAGE_TITLE, 67513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch IDS_NEW_TAB_THEMES_GALLERY_PAGE_TITLE }; 68513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 69513209b27ff55e2841eac0e4120199c23acce758Ben Murdochnamespace { 70513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 71513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// HistoryDBTask used during migration of thumbnails from history to top sites. 72513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// When run on the history thread it collects the top sites and the 73513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// corresponding thumbnails. When run back on the ui thread it calls into 74513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// TopSites::FinishHistoryMigration. 75513209b27ff55e2841eac0e4120199c23acce758Ben Murdochclass LoadThumbnailsFromHistoryTask : public HistoryDBTask { 76513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch public: 77513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LoadThumbnailsFromHistoryTask(TopSites* top_sites, 78513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int result_count) 79513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch : top_sites_(top_sites), 80513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch result_count_(result_count) { 81513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // l10n_util isn't thread safe, so cache for use on the db thread. 82513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ignore_urls_.insert(l10n_util::GetStringUTF8(IDS_CHROME_WELCOME_URL)); 83513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ignore_urls_.insert(l10n_util::GetStringUTF8(IDS_THEMES_GALLERY_URL)); 84513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 85513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 86513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch virtual bool RunOnDBThread(history::HistoryBackend* backend, 87513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch history::HistoryDatabase* db) { 88513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Get the most visited urls. 89513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch backend->QueryMostVisitedURLsImpl(result_count_, 90513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch kDaysOfHistory, 91513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch &data_.most_visited); 92513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 93513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // And fetch the thumbnails. 94513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (size_t i = 0; i < data_.most_visited.size(); ++i) { 95513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const GURL& url = data_.most_visited[i].url; 96513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (ShouldFetchThumbnailFor(url)) { 97513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<RefCountedBytes> data; 98513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch backend->GetPageThumbnailDirectly(url, &data); 99513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch data_.url_to_thumbnail_map[url] = data; 100513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 101513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 102513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return true; 103513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 104513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 105513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch virtual void DoneRunOnMainThread() { 106513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch top_sites_->FinishHistoryMigration(data_); 107513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 108513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 109513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch private: 110513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool ShouldFetchThumbnailFor(const GURL& url) { 111513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return ignore_urls_.find(url.spec()) == ignore_urls_.end(); 112513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 113513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 114513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Set of URLs we don't load thumbnails for. This is created on the UI thread 115513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // and used on the history thread. 116513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::set<std::string> ignore_urls_; 117513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 118513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<TopSites> top_sites_; 119513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 120513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Number of results to request from history. 121513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const int result_count_; 122513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 123513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ThumbnailMigration data_; 124513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 125513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DISALLOW_COPY_AND_ASSIGN(LoadThumbnailsFromHistoryTask); 126513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}; 127513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 128513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} // namespace 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 130513209b27ff55e2841eac0e4120199c23acce758Ben MurdochTopSites::TopSites(Profile* profile) 13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : backend_(NULL), 132513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch cache_(new TopSitesCache()), 133513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch thread_safe_cache_(new TopSitesCache()), 134513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch profile_(profile), 135513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch last_num_urls_changed_(0), 136513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch blacklist_(NULL), 137513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch pinned_urls_(NULL), 138513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch history_state_(HISTORY_LOADING), 139513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch top_sites_state_(TOP_SITES_LOADING), 140513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch loaded_(false) { 1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!profile_) 1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (NotificationService::current()) { 1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick registrar_.Add(this, NotificationType::HISTORY_URLS_DELETED, 1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Source<Profile>(profile_)); 1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, 1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NotificationService::AllSources()); 1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We create update objects here to be sure that dictionaries are created 152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // in the user preferences. 153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryPrefUpdate(profile_->GetPrefs(), 154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs::kNTPMostVisitedURLsBlacklist).Get(); 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryPrefUpdate(profile_->GetPrefs(), 156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs::kNTPMostVisitedPinnedURLs).Get(); 157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Now the dictionaries are guaranteed to exist and we can cache pointers 159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // to them. 160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen blacklist_ = 161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen profile_->GetPrefs()->GetDictionary(prefs::kNTPMostVisitedURLsBlacklist); 162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen pinned_urls_ = 163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen profile_->GetPrefs()->GetDictionary(prefs::kNTPMostVisitedPinnedURLs); 1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TopSites::Init(const FilePath& db_name) { 16772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Create the backend here, rather than in the constructor, so that 16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // unit tests that do not need the backend can run without a problem. 16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen backend_ = new TopSitesBackend; 170513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch backend_->Init(db_name); 171513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch backend_->GetMostVisitedThumbnails( 172513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch &cancelable_consumer_, 173513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NewCallback(this, &TopSites::OnGotMostVisitedThumbnails)); 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 175513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // History may have already finished loading by the time we're created. 176513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch HistoryService* history = profile_->GetHistoryServiceWithoutCreating(); 177513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (history && history->backend_loaded()) { 178513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (history->needs_top_sites_migration()) 179513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MigrateFromHistory(); 180513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch else 181513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch history_state_ = HISTORY_LOADED; 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TopSites::SetPageThumbnail(const GURL& url, 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const SkBitmap& thumbnail, 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ThumbnailScore& score) { 188513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 189513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 190513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!loaded_) { 191513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // TODO(sky): I need to cache these and apply them after the load 192513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // completes. 193513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 194513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 195513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool add_temp_thumbnail = false; 19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!IsKnownURL(url)) { 19872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!IsFull()) { 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch add_temp_thumbnail = true; 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; // This URL is not known to us. 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!HistoryService::CanAddURL(url)) 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; // It's not a real webpage. 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 208513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<RefCountedBytes> thumbnail_data; 209513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!EncodeBitmap(thumbnail, &thumbnail_data)) 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (add_temp_thumbnail) { 213513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Always remove the existing entry and then add it back. That way if we end 214513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // up with too many temp thumbnails we'll prune the oldest first. 215513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch RemoveTemporaryThumbnailByURL(url); 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddTemporaryThumbnail(url, thumbnail_data, score); 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return SetPageThumbnailEncoded(url, thumbnail_data, score); 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 223513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::GetMostVisitedURLs(CancelableRequestConsumer* consumer, 224513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GetTopSitesCallback* callback) { 225513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // WARNING: this may be invoked on any thread. 226513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<CancelableRequest<GetTopSitesCallback> > request( 227513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new CancelableRequest<GetTopSitesCallback>(callback)); 2283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // This ensures cancellation of requests when either the consumer or the 229513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // provider is deleted. Deletion of requests is also guaranteed. 230513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch AddRequest(request, consumer); 231513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MostVisitedURLList filtered_urls; 232513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch { 23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 234513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!loaded_) { 235513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // A request came in before we finished loading. Put the request in 236513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // pending_callbacks_ and we'll notify it when we finish loading. 237513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch pending_callbacks_.insert(request); 238513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return; 239513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 241513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch filtered_urls = thread_safe_cache_->top_sites(); 242513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 243513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch request->ForwardResult(GetTopSitesCallback::TupleType(filtered_urls)); 244513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 246513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool TopSites::GetPageThumbnail(const GURL& url, 247513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<RefCountedBytes>* bytes) { 248513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // WARNING: this may be invoked on any thread. 24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 250513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return thread_safe_cache_->GetPageThumbnail(url, bytes); 251513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 252513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 25372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool TopSites::GetPageThumbnailScore(const GURL& url, 25472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ThumbnailScore* score) { 25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // WARNING: this may be invoked on any thread. 25672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return thread_safe_cache_->GetPageThumbnailScore(url, score); 25872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool TopSites::GetTemporaryPageThumbnailScore(const GURL& url, 261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ThumbnailScore* score) { 262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (TempImages::iterator i = temp_images_.begin(); i != temp_images_.end(); 263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ++i) { 264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (i->first == url) { 265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *score = i->second.thumbnail_score; 266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 273513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Returns the index of |url| in |urls|, or -1 if not found. 274513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstatic int IndexOf(const MostVisitedURLList& urls, const GURL& url) { 275513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (size_t i = 0; i < urls.size(); i++) { 276513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (urls[i].url == url) 277513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return i; 278513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 279513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return -1; 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 282513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::MigrateFromHistory() { 283513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 284513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK_EQ(history_state_, HISTORY_LOADING); 285513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 286513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch history_state_ = HISTORY_MIGRATING; 287513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch profile_->GetHistoryService(Profile::EXPLICIT_ACCESS)->ScheduleDBTask( 288513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new LoadThumbnailsFromHistoryTask( 289513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch this, 290513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch num_results_to_request_from_history()), 291513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch &cancelable_consumer_); 292513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MigratePinnedURLs(); 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 295513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::FinishHistoryMigration(const ThumbnailMigration& data) { 296513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 297513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK_EQ(history_state_, HISTORY_MIGRATING); 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 299513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch history_state_ = HISTORY_LOADED; 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 301513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SetTopSites(data.most_visited); 302513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 303513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (size_t i = 0; i < data.most_visited.size(); ++i) { 304513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch URLToThumbnailMap::const_iterator image_i = 305513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch data.url_to_thumbnail_map.find(data.most_visited[i].url); 306513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (image_i != data.url_to_thumbnail_map.end()) { 307513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SetPageThumbnailEncoded(data.most_visited[i].url, 308513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch image_i->second, 309513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ThumbnailScore()); 310513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 313513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MoveStateToLoaded(); 314513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 315513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ResetThreadSafeImageCache(); 316513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 317513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // We've scheduled all the thumbnails and top sites to be written to the top 318513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // sites db, but it hasn't happened yet. Schedule a request on the db thread 319513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // that notifies us when done. When done we'll know everything was written and 320513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // we can tell history to finish its part of migration. 321513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch backend_->DoEmptyRequest( 322513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch &cancelable_consumer_, 323513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NewCallback(this, &TopSites::OnHistoryMigrationWrittenToDisk)); 324513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 325513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 326513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::HistoryLoaded() { 327513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 328513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK_NE(history_state_, HISTORY_LOADED); 329513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 330513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (history_state_ != HISTORY_MIGRATING) { 331513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // No migration from history is needed. 332513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch history_state_ = HISTORY_LOADED; 333513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (top_sites_state_ == TOP_SITES_LOADED_WAITING_FOR_HISTORY) { 334513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // TopSites thought it needed migration, but it really didn't. This 335513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // typically happens the first time a profile is run with Top Sites 336513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // enabled 337513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SetTopSites(MostVisitedURLList()); 338513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MoveStateToLoaded(); 339513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 340513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 341513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 342513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 343513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool TopSites::HasBlacklistedItems() const { 344513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return !blacklist_->empty(); 345513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 346513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 347513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::AddBlacklistedURL(const GURL& url) { 348513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 349513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 350513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch RemovePinnedURL(url); 351513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Value* dummy = Value::CreateNullValue(); 352ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { 353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryPrefUpdate update(profile_->GetPrefs(), 354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs::kNTPMostVisitedURLsBlacklist); 355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* blacklist = update.Get(); 356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen blacklist->SetWithoutPathExpansion(GetURLHash(url), dummy); 357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 358513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 359513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ResetThreadSafeCache(); 360513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 361513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 362513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::RemoveBlacklistedURL(const GURL& url) { 363513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { 365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryPrefUpdate update(profile_->GetPrefs(), 366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs::kNTPMostVisitedURLsBlacklist); 367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* blacklist = update.Get(); 368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen blacklist->RemoveWithoutPathExpansion(GetURLHash(url), NULL); 369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 370513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ResetThreadSafeCache(); 371513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 372513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 373513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool TopSites::IsBlacklisted(const GURL& url) { 374513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 375513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return blacklist_->HasKey(GetURLHash(url)); 376513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 377513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 378513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::ClearBlacklistedURLs() { 379513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { 381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryPrefUpdate update(profile_->GetPrefs(), 382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs::kNTPMostVisitedURLsBlacklist); 383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* blacklist = update.Get(); 384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen blacklist->Clear(); 385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 386513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ResetThreadSafeCache(); 387513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 388513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 389513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::AddPinnedURL(const GURL& url, size_t pinned_index) { 390513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 391513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 392513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GURL old; 393513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (GetPinnedURLAtIndex(pinned_index, &old)) 394513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch RemovePinnedURL(old); 395513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 396513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (IsURLPinned(url)) 397513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch RemovePinnedURL(url); 398513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 399513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Value* index = Value::CreateIntegerValue(pinned_index); 400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { 402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryPrefUpdate update(profile_->GetPrefs(), 403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs::kNTPMostVisitedPinnedURLs); 404ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* pinned_urls = update.Get(); 405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen pinned_urls->SetWithoutPathExpansion(GetURLString(url), index); 406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 407513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 408513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ResetThreadSafeCache(); 409513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 410513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 411513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool TopSites::IsURLPinned(const GURL& url) { 412513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int tmp; 413513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return pinned_urls_->GetIntegerWithoutPathExpansion(GetURLString(url), &tmp); 414513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 415513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 416513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::RemovePinnedURL(const GURL& url) { 417513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 418513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 419ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { 420ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryPrefUpdate update(profile_->GetPrefs(), 421ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs::kNTPMostVisitedPinnedURLs); 422ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* pinned_urls = update.Get(); 423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen pinned_urls->RemoveWithoutPathExpansion(GetURLString(url), NULL); 424ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 425513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 426513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ResetThreadSafeCache(); 427513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 428513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 429513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool TopSites::GetPinnedURLAtIndex(size_t index, GURL* url) { 430513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (DictionaryValue::key_iterator it = pinned_urls_->begin_keys(); 431513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch it != pinned_urls_->end_keys(); ++it) { 432513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int current_index; 433513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (pinned_urls_->GetIntegerWithoutPathExpansion(*it, ¤t_index)) { 434513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (static_cast<size_t>(current_index) == index) { 435513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch *url = GURL(*it); 436513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return true; 437513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 438513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 439513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 440513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 441513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 442513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 443513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::Shutdown() { 444513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch profile_ = NULL; 445513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Cancel all requests so that the service doesn't callback to us after we've 446513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // invoked Shutdown (this could happen if we have a pending request and 447513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Shutdown is invoked). 448513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch cancelable_consumer_.CancelAllRequests(); 449513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch backend_->Shutdown(); 450513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 451513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 452513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static 453513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::DiffMostVisited(const MostVisitedURLList& old_list, 454513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const MostVisitedURLList& new_list, 455513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch TopSitesDelta* delta) { 456513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Add all the old URLs for quick lookup. This maps URLs to the corresponding 457513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // index in the input. 458513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::map<GURL, size_t> all_old_urls; 459513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (size_t i = 0; i < old_list.size(); i++) 460513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch all_old_urls[old_list[i].url] = i; 461513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 462513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Check all the URLs in the new set to see which ones are new or just moved. 463513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // When we find a match in the old set, we'll reset its index to our special 464513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // marker. This allows us to quickly identify the deleted ones in a later 465513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // pass. 466513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const size_t kAlreadyFoundMarker = static_cast<size_t>(-1); 467513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (size_t i = 0; i < new_list.size(); i++) { 468513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::map<GURL, size_t>::iterator found = all_old_urls.find(new_list[i].url); 469513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (found == all_old_urls.end()) { 470513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MostVisitedURLWithRank added; 471513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch added.url = new_list[i]; 472513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch added.rank = i; 473513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch delta->added.push_back(added); 474513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else { 475513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (found->second != i) { 476513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MostVisitedURLWithRank moved; 477513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch moved.url = new_list[i]; 478513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch moved.rank = i; 479513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch delta->moved.push_back(moved); 480513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 481513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch found->second = kAlreadyFoundMarker; 482513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 483513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 484513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 485513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Any member without the special marker in the all_old_urls list means that 486513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // there wasn't a "new" URL that mapped to it, so it was deleted. 487513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (std::map<GURL, size_t>::const_iterator i = all_old_urls.begin(); 488513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch i != all_old_urls.end(); ++i) { 489513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (i->second != kAlreadyFoundMarker) 490513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch delta->deleted.push_back(old_list[i->second]); 491513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 492513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 493513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 494201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochCancelableRequestProvider::Handle TopSites::StartQueryForMostVisited() { 495201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(loaded_); 496201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!profile_) 49772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return 0; 498201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 499201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); 500201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // |hs| may be null during unit tests. 501201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (hs) { 502201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return hs->QueryMostVisitedURLs( 503201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch num_results_to_request_from_history(), 504201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kDaysOfHistory, 505201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &cancelable_consumer_, 506201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NewCallback(this, &TopSites::OnTopSitesAvailableFromHistory)); 507201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 50872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return 0; 50972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 51072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 51172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool TopSites::IsKnownURL(const GURL& url) { 51272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return loaded_ && cache_->IsKnownURL(url); 51372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 51472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 51572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool TopSites::IsFull() { 51672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return loaded_ && cache_->top_sites().size() >= kTopSitesNumber; 517201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 518201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 519513209b27ff55e2841eac0e4120199c23acce758Ben MurdochTopSites::~TopSites() { 520513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 521513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 522513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool TopSites::SetPageThumbnailNoDB(const GURL& url, 523513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const RefCountedBytes* thumbnail_data, 524513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const ThumbnailScore& score) { 525513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // This should only be invoked when we know about the url. 526513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(cache_->IsKnownURL(url)); 527513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 528513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const MostVisitedURL& most_visited = 529513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch cache_->top_sites()[cache_->GetURLIndex(url)]; 530513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Images* image = cache_->GetImage(url); 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // When comparing the thumbnail scores, we need to take into account the 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // redirect hops, which are not generated when the thumbnail is because the 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // redirects weren't known. We fill that in here since we know the redirects. 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ThumbnailScore new_score_with_redirects(score); 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_score_with_redirects.redirect_hops_from_dest = 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetRedirectDistanceForURL(most_visited, url); 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 539513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!ShouldReplaceThumbnailWith(image->thumbnail_score, 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_score_with_redirects) && 541513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch image->thumbnail.get()) 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; // The one we already have is better. 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 544513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch image->thumbnail = const_cast<RefCountedBytes*>(thumbnail_data); 545513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch image->thumbnail_score = new_score_with_redirects; 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 547513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ResetThreadSafeImageCache(); 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 551513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool TopSites::SetPageThumbnailEncoded(const GURL& url, 552513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const RefCountedBytes* thumbnail, 553513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const ThumbnailScore& score) { 554513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!SetPageThumbnailNoDB(url, thumbnail, score)) 555513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 556513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 557513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Update the database. 558513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!cache_->IsKnownURL(url)) 559513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 560513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 561513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch size_t index = cache_->GetURLIndex(url); 562513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const MostVisitedURL& most_visited = cache_->top_sites()[index]; 563513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch backend_->SetPageThumbnail(most_visited, 564513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch index, 565513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch *(cache_->GetImage(most_visited.url))); 566513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return true; 567513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 568513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 569513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static 570513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool TopSites::EncodeBitmap(const SkBitmap& bitmap, 571513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<RefCountedBytes>* bytes) { 572513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch *bytes = new RefCountedBytes(); 573513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SkAutoLockPixels bitmap_lock(bitmap); 574513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::vector<unsigned char> data; 575513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!gfx::JPEGCodec::Encode( 576513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)), 577513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch gfx::JPEGCodec::FORMAT_BGRA, bitmap.width(), 578513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bitmap.height(), 579513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch static_cast<int>(bitmap.rowBytes()), 90, 580513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch &data)) { 581513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 582513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 583513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // As we're going to cache this data, make sure the vector is only as big as 584513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // it needs to be. 585513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch (*bytes)->data = data; 586513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return true; 587513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 588513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 589513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::RemoveTemporaryThumbnailByURL(const GURL& url) { 590513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (TempImages::iterator i = temp_images_.begin(); i != temp_images_.end(); 591513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ++i) { 592513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (i->first == url) { 593513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch temp_images_.erase(i); 5943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 5953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 599513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::AddTemporaryThumbnail(const GURL& url, 600513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const RefCountedBytes* thumbnail, 601513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const ThumbnailScore& score) { 602513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (temp_images_.size() == kMaxTempTopImages) 603513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch temp_images_.erase(temp_images_.begin()); 604513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 605513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch TempImage image; 606513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch image.first = url; 607513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch image.second.thumbnail = const_cast<RefCountedBytes*>(thumbnail); 608513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch image.second.thumbnail_score = score; 609513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch temp_images_.push_back(image); 610513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 611513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 612201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid TopSites::TimerFired() { 613201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch StartQueryForMostVisited(); 614513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 616513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static 617513209b27ff55e2841eac0e4120199c23acce758Ben Murdochint TopSites::GetRedirectDistanceForURL(const MostVisitedURL& most_visited, 618513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const GURL& url) { 619513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (size_t i = 0; i < most_visited.redirects.size(); i++) { 620513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (most_visited.redirects[i] == url) 621513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return static_cast<int>(most_visited.redirects.size() - i - 1); 622513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 623513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NOTREACHED() << "URL should always be found."; 624513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return 0; 625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 627513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static 628513209b27ff55e2841eac0e4120199c23acce758Ben MurdochMostVisitedURLList TopSites::GetPrepopulatePages() { 629513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MostVisitedURLList urls; 630513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch urls.resize(arraysize(kPrepopulatePageIDs)); 631513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (size_t i = 0; i < arraysize(kPrepopulatePageIDs); ++i) { 632513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MostVisitedURL& url = urls[i]; 633513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch url.url = GURL(l10n_util::GetStringUTF8(kPrepopulatePageIDs[i])); 634513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch url.redirects.push_back(url.url); 635513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch url.favicon_url = GURL(kPrepopulateFaviconURLs[i]); 636513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch url.title = l10n_util::GetStringUTF16(kPrepopulateTitleIDs[i]); 6373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 638513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return urls; 6393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 6403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 641513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static 6423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool TopSites::AddPrepopulatedPages(MostVisitedURLList* urls) { 6433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool added = false; 644513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MostVisitedURLList prepopulate_urls = GetPrepopulatePages(); 645513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (size_t i = 0; i < prepopulate_urls.size(); ++i) { 646513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (urls->size() < kTopSitesNumber && 647513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch IndexOf(*urls, prepopulate_urls[i].url) == -1) { 648513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch urls->push_back(prepopulate_urls[i]); 649513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch added = true; 650513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 6513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 6523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return added; 6533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 6543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TopSites::MigratePinnedURLs() { 656513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 657513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 6583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::map<GURL, size_t> tmp_map; 6593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (DictionaryValue::key_iterator it = pinned_urls_->begin_keys(); 6603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick it != pinned_urls_->end_keys(); ++it) { 6613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Value* value; 6623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!pinned_urls_->GetWithoutPathExpansion(*it, &value)) 6633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick continue; 6643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (value->IsType(DictionaryValue::TYPE_DICTIONARY)) { 6663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DictionaryValue* dict = static_cast<DictionaryValue*>(value); 6673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string url_string; 6683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int index; 6693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (dict->GetString("url", &url_string) && 6703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick dict->GetInteger("index", &index)) 6713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick tmp_map[GURL(url_string)] = index; 6723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 6733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 674ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 675ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { 676ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryPrefUpdate update(profile_->GetPrefs(), 677ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs::kNTPMostVisitedPinnedURLs); 678ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* pinned_urls = update.Get(); 679ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen pinned_urls->Clear(); 680ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 681ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (std::map<GURL, size_t>::iterator it = tmp_map.begin(); 6833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick it != tmp_map.end(); ++it) 6843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AddPinnedURL(it->first, it->second); 6853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 6863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TopSites::ApplyBlacklistAndPinnedURLs(const MostVisitedURLList& urls, 6883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MostVisitedURLList* out) { 6893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MostVisitedURLList urls_copy; 6903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (size_t i = 0; i < urls.size(); i++) { 6913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!IsBlacklisted(urls[i].url)) 6923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick urls_copy.push_back(urls[i]); 6933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 6943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (size_t pinned_index = 0; pinned_index < kTopSitesShown; pinned_index++) { 6963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GURL url; 6973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool found = GetPinnedURLAtIndex(pinned_index, &url); 6983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!found) 6993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick continue; 7003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(!url.is_empty()); 7023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int cur_index = IndexOf(urls_copy, url); 7033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MostVisitedURL tmp; 7043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (cur_index < 0) { 7053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Pinned URL not in urls. 7063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick tmp.url = url; 7073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 7083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick tmp = urls_copy[cur_index]; 7093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick urls_copy.erase(urls_copy.begin() + cur_index); 7103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 7113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (pinned_index > out->size()) 7123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out->resize(pinned_index); // Add empty URLs as fillers. 7133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out->insert(out->begin() + pinned_index, tmp); 7143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 7153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Add non-pinned URLs in the empty spots. 7173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick size_t current_url = 0; // Index into the remaining URLs in urls_copy. 7183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (size_t i = 0; i < kTopSitesShown && current_url < urls_copy.size(); 7193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick i++) { 7203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (i == out->size()) { 7213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out->push_back(urls_copy[current_url]); 7223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick current_url++; 7233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else if (i < out->size()) { 7243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if ((*out)[i].url.is_empty()) { 7253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Replace the filler 7263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick (*out)[i] = urls_copy[current_url]; 7273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick current_url++; 7283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 7293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 7303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 7313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 7323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 7333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 7343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstd::string TopSites::GetURLString(const GURL& url) { 736513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return cache_->GetCanonicalURL(url).spec(); 7373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 7383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstd::string TopSites::GetURLHash(const GURL& url) { 7403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We don't use canonical URLs here to be able to blacklist only one of 7413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // the two 'duplicate' sites, e.g. 'gmail.com' and 'mail.google.com'. 7423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return MD5String(url.spec()); 7433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 7443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 745513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbase::TimeDelta TopSites::GetUpdateDelay() { 746513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (cache_->top_sites().size() <= arraysize(kPrepopulateTitleIDs)) 747513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return base::TimeDelta::FromSeconds(30); 748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 749513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int64 range = kMaxUpdateIntervalMinutes - kMinUpdateIntervalMinutes; 750513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int64 minutes = kMaxUpdateIntervalMinutes - 751513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch last_num_urls_changed_ * range / cache_->top_sites().size(); 752513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return base::TimeDelta::FromMinutes(minutes); 753513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 7543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 755513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static 756513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::ProcessPendingCallbacks( 757513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const PendingCallbackSet& pending_callbacks, 758513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const MostVisitedURLList& urls) { 759513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PendingCallbackSet::const_iterator i; 760513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (i = pending_callbacks.begin(); 761513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch i != pending_callbacks.end(); ++i) { 762513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<CancelableRequest<GetTopSitesCallback> > request = *i; 763513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!request->canceled()) 764513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch request->ForwardResult(GetTopSitesCallback::TupleType(urls)); 765513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 766513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 7673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 768513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::Observe(NotificationType type, 769513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const NotificationSource& source, 770513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const NotificationDetails& details) { 771513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!loaded_) 772513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return; 773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 774513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (type == NotificationType::HISTORY_URLS_DELETED) { 775513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Details<history::URLsDeletedDetails> deleted_details(details); 776513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (deleted_details->all_history) { 777513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SetTopSites(MostVisitedURLList()); 778513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch backend_->ResetDatabase(); 779513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else { 780513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::set<size_t> indices_to_delete; // Indices into top_sites_. 781513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (std::set<GURL>::iterator i = deleted_details->urls.begin(); 782513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch i != deleted_details->urls.end(); ++i) { 783513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (cache_->IsKnownURL(*i)) 784513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch indices_to_delete.insert(cache_->GetURLIndex(*i)); 785513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 787513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (indices_to_delete.empty()) 788513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return; 789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 790513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MostVisitedURLList new_top_sites(cache_->top_sites()); 791513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (std::set<size_t>::reverse_iterator i = indices_to_delete.rbegin(); 792513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch i != indices_to_delete.rend(); i++) { 793513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch size_t index = *i; 794513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch RemovePinnedURL(new_top_sites[index].url); 795513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new_top_sites.erase(new_top_sites.begin() + index); 796513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 797513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SetTopSites(new_top_sites); 798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 799513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch StartQueryForMostVisited(); 800513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else if (type == NotificationType::NAV_ENTRY_COMMITTED) { 80172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!IsFull()) { 802513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NavigationController::LoadCommittedDetails* load_details = 803513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Details<NavigationController::LoadCommittedDetails>(details).ptr(); 804513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!load_details) 805513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return; 806513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const GURL& url = load_details->entry->url(); 807513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!cache_->IsKnownURL(url) && HistoryService::CanAddURL(url)) { 808513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // To avoid slamming history we throttle requests when the url updates. 809513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // To do otherwise negatively impacts perf tests. 810513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch RestartQueryForTopSitesTimer(GetUpdateDelay()); 811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 816513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::SetTopSites(const MostVisitedURLList& new_top_sites) { 817513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 8183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 819513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MostVisitedURLList top_sites(new_top_sites); 820513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch AddPrepopulatedPages(&top_sites); 821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 822513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch TopSitesDelta delta; 823513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DiffMostVisited(cache_->top_sites(), top_sites, &delta); 824513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!delta.deleted.empty() || !delta.added.empty() || !delta.moved.empty()) 825513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch backend_->UpdateTopSites(delta); 8263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 827513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch last_num_urls_changed_ = delta.added.size() + delta.moved.size(); 828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 829513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // We always do the following steps (setting top sites in cache, and resetting 830513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // thread safe cache ...) as this method is invoked during startup at which 831513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // point the caches haven't been updated yet. 832513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch cache_->SetTopSites(top_sites); 8333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 834513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // See if we have any tmp thumbnails for the new sites. 835513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!temp_images_.empty()) { 836513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (size_t i = 0; i < top_sites.size(); ++i) { 837513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const MostVisitedURL& mv = top_sites[i]; 838513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GURL canonical_url = cache_->GetCanonicalURL(mv.url); 839513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // At the time we get the thumbnail redirects aren't known, so we have to 840513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // iterate through all the images. 841513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (TempImages::iterator it = temp_images_.begin(); 842513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch it != temp_images_.end(); ++it) { 843513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (canonical_url == cache_->GetCanonicalURL(it->first)) { 844513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SetPageThumbnailEncoded(mv.url, 845513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch it->second.thumbnail, 8463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick it->second.thumbnail_score); 847513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch temp_images_.erase(it); 8483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 8493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 852513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 8533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 854513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (top_sites.size() >= kTopSitesNumber) 855513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch temp_images_.clear(); 8563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 857513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ResetThreadSafeCache(); 858513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ResetThreadSafeImageCache(); 859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 860513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Restart the timer that queries history for top sites. This is done to 861513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // ensure we stay in sync with history. 862513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch RestartQueryForTopSitesTimer(GetUpdateDelay()); 863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 865513209b27ff55e2841eac0e4120199c23acce758Ben Murdochint TopSites::num_results_to_request_from_history() const { 866513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 868513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return kTopSitesNumber + blacklist_->size(); 869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 871513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::MoveStateToLoaded() { 872513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 874513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MostVisitedURLList filtered_urls; 875513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PendingCallbackSet pending_callbacks; 876513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch { 87772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 879513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (loaded_) 880513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return; // Don't do anything if we're already loaded. 881513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch loaded_ = true; 882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 883513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Now that we're loaded we can service the queued up callbacks. Copy them 884513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // here and service them outside the lock. 885513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!pending_callbacks_.empty()) { 886513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch filtered_urls = thread_safe_cache_->top_sites(); 887513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch pending_callbacks.swap(pending_callbacks_); 888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 891513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ProcessPendingCallbacks(pending_callbacks, filtered_urls); 8923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 893513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NotificationService::current()->Notify(NotificationType::TOP_SITES_LOADED, 894513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Source<Profile>(profile_), 895513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Details<TopSites>(this)); 8963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 8973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 898513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::ResetThreadSafeCache() { 89972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 900513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MostVisitedURLList cached; 901513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ApplyBlacklistAndPinnedURLs(cache_->top_sites(), &cached); 902513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch thread_safe_cache_->SetTopSites(cached); 9033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 9043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 905513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::ResetThreadSafeImageCache() { 90672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 907513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch thread_safe_cache_->SetThumbnails(cache_->images()); 908513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch thread_safe_cache_->RemoveUnreferencedThumbnails(); 9093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 9103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 911513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::RestartQueryForTopSitesTimer(base::TimeDelta delta) { 912513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (timer_.IsRunning() && ((timer_start_time_ + timer_.GetCurrentDelay()) < 913513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch (base::TimeTicks::Now() + delta))) { 914513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return; 9153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 9163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 917513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch timer_start_time_ = base::TimeTicks::Now(); 918513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch timer_.Stop(); 919201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch timer_.Start(delta, this, &TopSites::TimerFired); 9203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 9213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 922513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::OnHistoryMigrationWrittenToDisk(TopSitesBackend::Handle handle) { 923513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 9243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 925513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!profile_) 9263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 928513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch HistoryService* history = 929513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); 930513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (history) 931513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch history->OnTopSitesReady(); 932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 934513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::OnGotMostVisitedThumbnails( 935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CancelableRequestProvider::Handle handle, 936513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<MostVisitedThumbnails> data, 937513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool may_need_history_migration) { 938513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 939513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK_EQ(top_sites_state_, TOP_SITES_LOADING); 940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 941513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!may_need_history_migration) { 942513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch top_sites_state_ = TOP_SITES_LOADED; 9433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 944513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Set the top sites directly in the cache so that SetTopSites diffs 945513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // correctly. 946513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch cache_->SetTopSites(data->most_visited); 947513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SetTopSites(data->most_visited); 948513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch cache_->SetThumbnails(data->url_to_images_map); 9493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 950513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ResetThreadSafeImageCache(); 951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 952513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MoveStateToLoaded(); 953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 954513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Start a timer that refreshes top sites from history. 955513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch RestartQueryForTopSitesTimer( 956513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::TimeDelta::FromSeconds(kUpdateIntervalSecs)); 957513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else { 958513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // The top sites file didn't exist or is the wrong version. We need to wait 959513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // for history to finish loading to know if we really needed to migrate. 960513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (history_state_ == HISTORY_LOADED) { 961513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch top_sites_state_ = TOP_SITES_LOADED; 962513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SetTopSites(MostVisitedURLList()); 963513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MoveStateToLoaded(); 964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 965513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch top_sites_state_ = TOP_SITES_LOADED_WAITING_FOR_HISTORY; 966513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Ask for history just in case it hasn't been loaded yet. When history 967513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // finishes loading we'll do migration and/or move to loaded. 968513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); 969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 973513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TopSites::OnTopSitesAvailableFromHistory( 974513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CancelableRequestProvider::Handle handle, 975513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch MostVisitedURLList pages) { 976513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SetTopSites(pages); 977201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 978201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Used only in testing. 979201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NotificationService::current()->Notify( 980201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NotificationType::TOP_SITES_UPDATED, 981201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch Source<TopSites>(this), 982201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch Details<CancelableRequestProvider::Handle>(&handle)); 983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace history 986