1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/ui/webui/ntp/suggestions_source_top_sites.h" 6 7 #include "base/bind.h" 8 #include "base/bind_helpers.h" 9 #include "base/command_line.h" 10 #include "base/stl_util.h" 11 #include "base/strings/string_number_conversions.h" 12 #include "base/values.h" 13 #include "chrome/browser/history/history_service_factory.h" 14 #include "chrome/browser/history/top_sites.h" 15 #include "chrome/browser/history/visit_filter.h" 16 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h" 18 #include "chrome/browser/ui/webui/ntp/suggestions_combiner.h" 19 #include "chrome/common/chrome_switches.h" 20 21 22 namespace { 23 24 // The weight used by the combiner to determine which ratio of suggestions 25 // should be obtained from this source. 26 const int kSuggestionsTopListWeight = 1; 27 28 } // namespace 29 30 SuggestionsSourceTopSites::SuggestionsSourceTopSites() 31 : combiner_(NULL), 32 debug_(false) { 33 } 34 35 SuggestionsSourceTopSites::~SuggestionsSourceTopSites() { 36 STLDeleteElements(&items_); 37 } 38 39 void SuggestionsSourceTopSites::SetDebug(bool enable) { 40 debug_ = enable; 41 } 42 43 inline int SuggestionsSourceTopSites::GetWeight() { 44 return kSuggestionsTopListWeight; 45 } 46 47 int SuggestionsSourceTopSites::GetItemCount() { 48 return items_.size(); 49 } 50 51 base::DictionaryValue* SuggestionsSourceTopSites::PopItem() { 52 if (items_.empty()) 53 return NULL; 54 55 base::DictionaryValue* item = items_.front(); 56 items_.pop_front(); 57 return item; 58 } 59 60 void SuggestionsSourceTopSites::FetchItems(Profile* profile) { 61 DCHECK(combiner_); 62 STLDeleteElements(&items_); 63 64 history_tracker_.TryCancelAll(); 65 HistoryService* history = HistoryServiceFactory::GetForProfile( 66 profile, Profile::EXPLICIT_ACCESS); 67 // |history| may be null during unit tests. 68 if (history) { 69 history::VisitFilter time_filter; 70 time_filter.SetFilterTime(base::Time::Now()); 71 time_filter.SetFilterWidth(GetFilterWidth()); 72 time_filter.set_sorting_order(GetSortingOrder()); 73 74 history->QueryFilteredURLs( 75 0, 76 time_filter, 77 debug_, 78 base::Bind(&SuggestionsSourceTopSites::OnSuggestionsUrlsAvailable, 79 base::Unretained(this)), 80 &history_tracker_); 81 } 82 } 83 84 void SuggestionsSourceTopSites::SetCombiner(SuggestionsCombiner* combiner) { 85 DCHECK(!combiner_); 86 combiner_ = combiner; 87 } 88 89 void SuggestionsSourceTopSites::OnSuggestionsUrlsAvailable( 90 const history::FilteredURLList* data) { 91 DCHECK(data); 92 DCHECK(combiner_); 93 for (size_t i = 0; i < data->size(); i++) { 94 const history::FilteredURL& suggested_url = (*data)[i]; 95 if (suggested_url.url.is_empty()) 96 continue; 97 98 base::DictionaryValue* page_value = new base::DictionaryValue(); 99 NewTabUI::SetUrlTitleAndDirection(page_value, 100 suggested_url.title, 101 suggested_url.url); 102 page_value->SetDouble("score", suggested_url.score); 103 if (debug_) { 104 if (suggested_url.extended_info.total_visits) { 105 page_value->SetInteger("extended_info.total visits", 106 suggested_url.extended_info.total_visits); 107 } 108 if (suggested_url.extended_info.visits) { 109 page_value->SetInteger("extended_info.visits", 110 suggested_url.extended_info.visits); 111 } 112 if (suggested_url.extended_info.duration_opened) { 113 page_value->SetInteger("extended_info.duration opened", 114 suggested_url.extended_info.duration_opened); 115 } 116 if (!suggested_url.extended_info.last_visit_time.is_null()) { 117 base::TimeDelta deltaTime = 118 base::Time::Now() - suggested_url.extended_info.last_visit_time; 119 page_value->SetInteger("extended_info.seconds since last visit", 120 deltaTime.InSeconds()); 121 } 122 } 123 items_.push_back(page_value); 124 } 125 126 combiner_->OnItemsReady(); 127 } 128 129 // static 130 base::TimeDelta SuggestionsSourceTopSites::GetFilterWidth() { 131 return base::TimeDelta::FromHours(1); 132 } 133 134 // static 135 history::VisitFilter::SortingOrder 136 SuggestionsSourceTopSites::GetSortingOrder() { 137 return history::VisitFilter::ORDER_BY_RECENCY; 138 } 139