| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/search/instant_service.h" | 5 #include "chrome/browser/search/instant_service.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| 11 #include "build/build_config.h" | 11 #include "build/build_config.h" |
| 12 #include "chrome/browser/history/history_notifications.h" | 12 #include "chrome/browser/history/history_notifications.h" |
| 13 #include "chrome/browser/history/top_sites.h" | 13 #include "chrome/browser/history/top_sites.h" |
| 14 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
| 15 #include "chrome/browser/search/instant_io_context.h" | 15 #include "chrome/browser/search/instant_io_context.h" |
| 16 #include "chrome/browser/search/instant_service_factory.h" | 16 #include "chrome/browser/search/instant_service_factory.h" |
| 17 #include "chrome/browser/search/local_ntp_source.h" | 17 #include "chrome/browser/search/local_ntp_source.h" |
| 18 #include "chrome/browser/search/most_visited_iframe_source.h" | 18 #include "chrome/browser/search/most_visited_iframe_source.h" |
| 19 #include "chrome/browser/search/search.h" |
| 19 #include "chrome/browser/search/suggestion_iframe_source.h" | 20 #include "chrome/browser/search/suggestion_iframe_source.h" |
| 20 #include "chrome/browser/ui/browser.h" | 21 #include "chrome/browser/ui/browser.h" |
| 21 #include "chrome/browser/ui/browser_instant_controller.h" | 22 #include "chrome/browser/ui/browser_instant_controller.h" |
| 22 #include "chrome/browser/ui/browser_list.h" | 23 #include "chrome/browser/ui/browser_list.h" |
| 23 #include "chrome/browser/ui/host_desktop.h" | 24 #include "chrome/browser/ui/host_desktop.h" |
| 24 #include "chrome/browser/ui/search/instant_controller.h" | 25 #include "chrome/browser/ui/search/instant_controller.h" |
| 25 #include "chrome/browser/ui/webui/favicon_source.h" | 26 #include "chrome/browser/ui/webui/favicon_source.h" |
| 26 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" | 27 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" |
| 27 #include "chrome/browser/ui/webui/theme_source.h" | 28 #include "chrome/browser/ui/webui/theme_source.h" |
| 28 #include "chrome/common/chrome_notification_types.h" | 29 #include "chrome/common/chrome_notification_types.h" |
| 29 #include "content/public/browser/browser_thread.h" | 30 #include "content/public/browser/browser_thread.h" |
| 30 #include "content/public/browser/notification_service.h" | 31 #include "content/public/browser/notification_service.h" |
| 31 #include "content/public/browser/notification_types.h" | 32 #include "content/public/browser/notification_types.h" |
| 32 #include "content/public/browser/render_process_host.h" | 33 #include "content/public/browser/render_process_host.h" |
| 33 #include "content/public/browser/url_data_source.h" | 34 #include "content/public/browser/url_data_source.h" |
| 34 #include "googleurl/src/gurl.h" | 35 #include "googleurl/src/gurl.h" |
| 35 #include "net/url_request/url_request.h" | 36 #include "net/url_request/url_request.h" |
| 36 | 37 |
| 37 using content::BrowserThread; | 38 using content::BrowserThread; |
| 38 | 39 |
| 39 InstantService::InstantService(Profile* profile) | 40 InstantService::InstantService(Profile* profile) |
| 40 : profile_(profile), | 41 : profile_(profile), |
| 41 most_visited_item_cache_(kMaxInstantMostVisitedItemCacheSize), | |
| 42 weak_ptr_factory_(this) { | 42 weak_ptr_factory_(this) { |
| 43 // Stub for unit tests. | 43 // Stub for unit tests. |
| 44 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) | 44 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) |
| 45 return; | 45 return; |
| 46 | 46 |
| 47 registrar_.Add(this, | 47 registrar_.Add(this, |
| 48 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 48 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| 49 content::NotificationService::AllSources()); | 49 content::NotificationService::AllSources()); |
| 50 | 50 |
| 51 history::TopSites* top_sites = profile_->GetTopSites(); | 51 history::TopSites* top_sites = profile_->GetTopSites(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 71 content::URLDataSource::Add(profile, new FaviconSource( | 71 content::URLDataSource::Add(profile, new FaviconSource( |
| 72 profile, FaviconSource::FAVICON)); | 72 profile, FaviconSource::FAVICON)); |
| 73 content::URLDataSource::Add(profile, new LocalNtpSource()); | 73 content::URLDataSource::Add(profile, new LocalNtpSource()); |
| 74 content::URLDataSource::Add(profile, new SuggestionIframeSource()); | 74 content::URLDataSource::Add(profile, new SuggestionIframeSource()); |
| 75 content::URLDataSource::Add(profile, new MostVisitedIframeSource()); | 75 content::URLDataSource::Add(profile, new MostVisitedIframeSource()); |
| 76 } | 76 } |
| 77 | 77 |
| 78 InstantService::~InstantService() { | 78 InstantService::~InstantService() { |
| 79 } | 79 } |
| 80 | 80 |
| 81 // static | |
| 82 const std::string InstantService::MaybeTranslateInstantPathOnUI( | |
| 83 Profile* profile, const std::string& path) { | |
| 84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 85 InstantService* instant_service = | |
| 86 InstantServiceFactory::GetForProfile(profile); | |
| 87 if (!instant_service) | |
| 88 return path; | |
| 89 | |
| 90 InstantRestrictedID restricted_id = 0; | |
| 91 DCHECK_EQ(sizeof(InstantRestrictedID), sizeof(int)); | |
| 92 if (base::StringToInt(path, &restricted_id)) { | |
| 93 InstantMostVisitedItem item; | |
| 94 if (instant_service->GetMostVisitedItemForID(restricted_id, &item)) | |
| 95 return item.url.spec(); | |
| 96 } | |
| 97 return path; | |
| 98 } | |
| 99 | |
| 100 const std::string InstantService::MaybeTranslateInstantPathOnIO( | |
| 101 const net::URLRequest* request, const std::string& path) { | |
| 102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 103 | |
| 104 InstantRestrictedID restricted_id = 0; | |
| 105 DCHECK_EQ(sizeof(InstantRestrictedID), sizeof(int)); | |
| 106 if (base::StringToInt(path, &restricted_id)) { | |
| 107 GURL url; | |
| 108 if (InstantIOContext::GetURLForMostVisitedItemID(request, | |
| 109 restricted_id, | |
| 110 &url)) { | |
| 111 return url.spec(); | |
| 112 } | |
| 113 } | |
| 114 return path; | |
| 115 } | |
| 116 | |
| 117 // static | |
| 118 bool InstantService::IsInstantPath(const GURL& url) { | |
| 119 // Strip leading slash. | |
| 120 std::string path = url.path().substr(1); | |
| 121 | |
| 122 // Check that path is of Most Visited item ID form. | |
| 123 InstantRestrictedID dummy = 0; | |
| 124 return base::StringToInt(path, &dummy); | |
| 125 } | |
| 126 | |
| 127 void InstantService::AddInstantProcess(int process_id) { | 81 void InstantService::AddInstantProcess(int process_id) { |
| 128 process_ids_.insert(process_id); | 82 process_ids_.insert(process_id); |
| 129 | 83 |
| 130 if (instant_io_context_.get()) { | 84 if (instant_io_context_.get()) { |
| 131 BrowserThread::PostTask(BrowserThread::IO, | 85 BrowserThread::PostTask(BrowserThread::IO, |
| 132 FROM_HERE, | 86 FROM_HERE, |
| 133 base::Bind(&InstantIOContext::AddInstantProcessOnIO, | 87 base::Bind(&InstantIOContext::AddInstantProcessOnIO, |
| 134 instant_io_context_, | 88 instant_io_context_, |
| 135 process_id)); | 89 process_id)); |
| 136 } | 90 } |
| 137 } | 91 } |
| 138 | 92 |
| 139 bool InstantService::IsInstantProcess(int process_id) const { | 93 bool InstantService::IsInstantProcess(int process_id) const { |
| 140 return process_ids_.find(process_id) != process_ids_.end(); | 94 return process_ids_.find(process_id) != process_ids_.end(); |
| 141 } | 95 } |
| 142 | 96 |
| 143 void InstantService::AddMostVisitedItems( | |
| 144 const std::vector<InstantMostVisitedItem>& items) { | |
| 145 most_visited_item_cache_.AddItems(items); | |
| 146 | |
| 147 // Post task to the IO thread to copy the data. | |
| 148 if (instant_io_context_.get()) { | |
| 149 std::vector<InstantMostVisitedItemIDPair> items; | |
| 150 most_visited_item_cache_.GetCurrentItems(&items); | |
| 151 BrowserThread::PostTask( | |
| 152 BrowserThread::IO, FROM_HERE, | |
| 153 base::Bind(&InstantIOContext::AddMostVisitedItemsOnIO, | |
| 154 instant_io_context_, | |
| 155 items)); | |
| 156 } | |
| 157 } | |
| 158 | |
| 159 void InstantService::DeleteMostVisitedItem(const GURL& url) { | 97 void InstantService::DeleteMostVisitedItem(const GURL& url) { |
| 160 history::TopSites* top_sites = profile_->GetTopSites(); | 98 history::TopSites* top_sites = profile_->GetTopSites(); |
| 161 if (!top_sites) | 99 if (!top_sites) |
| 162 return; | 100 return; |
| 163 | 101 |
| 164 top_sites->AddBlacklistedURL(url); | 102 top_sites->AddBlacklistedURL(url); |
| 165 } | 103 } |
| 166 | 104 |
| 167 void InstantService::UndoMostVisitedDeletion(const GURL& url) { | 105 void InstantService::UndoMostVisitedDeletion(const GURL& url) { |
| 168 history::TopSites* top_sites = profile_->GetTopSites(); | 106 history::TopSites* top_sites = profile_->GetTopSites(); |
| 169 if (!top_sites) | 107 if (!top_sites) |
| 170 return; | 108 return; |
| 171 | 109 |
| 172 top_sites->RemoveBlacklistedURL(url); | 110 top_sites->RemoveBlacklistedURL(url); |
| 173 } | 111 } |
| 174 | 112 |
| 175 void InstantService::UndoAllMostVisitedDeletions() { | 113 void InstantService::UndoAllMostVisitedDeletions() { |
| 176 history::TopSites* top_sites = profile_->GetTopSites(); | 114 history::TopSites* top_sites = profile_->GetTopSites(); |
| 177 if (!top_sites) | 115 if (!top_sites) |
| 178 return; | 116 return; |
| 179 | 117 |
| 180 top_sites->ClearBlacklistedURLs(); | 118 top_sites->ClearBlacklistedURLs(); |
| 181 } | 119 } |
| 182 | 120 |
| 183 void InstantService::GetCurrentMostVisitedItems( | 121 void InstantService::GetCurrentMostVisitedItems( |
| 184 std::vector<InstantMostVisitedItemIDPair>* items) const { | 122 std::vector<InstantMostVisitedItem>* items) const { |
| 185 most_visited_item_cache_.GetCurrentItems(items); | 123 *items = most_visited_items_; |
| 186 } | 124 } |
| 187 | 125 |
| 188 void InstantService::Shutdown() { | 126 void InstantService::Shutdown() { |
| 189 process_ids_.clear(); | 127 process_ids_.clear(); |
| 190 | 128 |
| 191 if (instant_io_context_.get()) { | 129 if (instant_io_context_.get()) { |
| 192 BrowserThread::PostTask( | 130 BrowserThread::PostTask( |
| 193 BrowserThread::IO, | 131 BrowserThread::IO, |
| 194 FROM_HERE, | 132 FROM_HERE, |
| 195 base::Bind(&InstantIOContext::ClearInstantProcessesOnIO, | 133 base::Bind(&InstantIOContext::ClearInstantProcessesOnIO, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 224 base::Bind(&InstantService::OnMostVisitedItemsReceived, | 162 base::Bind(&InstantService::OnMostVisitedItemsReceived, |
| 225 weak_ptr_factory_.GetWeakPtr())); | 163 weak_ptr_factory_.GetWeakPtr())); |
| 226 } | 164 } |
| 227 break; | 165 break; |
| 228 } | 166 } |
| 229 default: | 167 default: |
| 230 NOTREACHED() << "Unexpected notification type in InstantService."; | 168 NOTREACHED() << "Unexpected notification type in InstantService."; |
| 231 } | 169 } |
| 232 } | 170 } |
| 233 | 171 |
| 234 bool InstantService::GetMostVisitedItemForID( | |
| 235 InstantRestrictedID most_visited_item_id, | |
| 236 InstantMostVisitedItem* item) const { | |
| 237 return most_visited_item_cache_.GetItemWithRestrictedID( | |
| 238 most_visited_item_id, item); | |
| 239 } | |
| 240 | |
| 241 void InstantService::OnMostVisitedItemsReceived( | 172 void InstantService::OnMostVisitedItemsReceived( |
| 242 const history::MostVisitedURLList& data) { | 173 const history::MostVisitedURLList& data) { |
| 243 // Android doesn't use Browser/BrowserList. Do nothing for Android platform. | 174 // Android doesn't use Browser/BrowserList. Do nothing for Android platform. |
| 244 #if !defined(OS_ANDROID) | 175 #if !defined(OS_ANDROID) |
| 245 history::MostVisitedURLList reordered_data(data); | 176 history::MostVisitedURLList reordered_data(data); |
| 246 history::TopSites::MaybeShuffle(&reordered_data); | 177 history::TopSites::MaybeShuffle(&reordered_data); |
| 247 | 178 |
| 248 std::vector<InstantMostVisitedItem> most_visited_items; | 179 std::vector<InstantMostVisitedItem> new_most_visited_items; |
| 249 for (size_t i = 0; i < reordered_data.size(); i++) { | 180 for (size_t i = 0; i < reordered_data.size(); i++) { |
| 250 const history::MostVisitedURL& url = reordered_data[i]; | 181 const history::MostVisitedURL& url = reordered_data[i]; |
| 251 InstantMostVisitedItem item; | 182 InstantMostVisitedItem item; |
| 252 item.url = url.url; | 183 item.url = url.url; |
| 253 item.title = url.title; | 184 item.title = url.title; |
| 254 most_visited_items.push_back(item); | 185 new_most_visited_items.push_back(item); |
| 255 } | 186 } |
| 256 AddMostVisitedItems(most_visited_items); | 187 if (chrome::AreMostVisitedItemsEqual(new_most_visited_items, |
| 188 most_visited_items_)) { |
| 189 return; |
| 190 } |
| 191 |
| 192 most_visited_items_ = new_most_visited_items; |
| 257 | 193 |
| 258 const BrowserList* browser_list = | 194 const BrowserList* browser_list = |
| 259 BrowserList::GetInstance(chrome::GetActiveDesktop()); | 195 BrowserList::GetInstance(chrome::GetActiveDesktop()); |
| 260 for (BrowserList::const_iterator it = browser_list->begin(); | 196 for (BrowserList::const_iterator it = browser_list->begin(); |
| 261 it != browser_list->end(); ++it) { | 197 it != browser_list->end(); ++it) { |
| 262 if ((*it)->profile() != profile_ || !((*it)->instant_controller())) | 198 if ((*it)->profile() != profile_ || !((*it)->instant_controller())) |
| 263 continue; | 199 continue; |
| 264 | 200 |
| 265 InstantController* controller = (*it)->instant_controller()->instant(); | 201 InstantController* controller = (*it)->instant_controller()->instant(); |
| 266 if (!controller) | 202 if (!controller) |
| 267 continue; | 203 continue; |
| 268 // TODO(kmadhusu): It would be cleaner to have each InstantController | 204 // TODO(kmadhusu): It would be cleaner to have each InstantController |
| 269 // register itself as an InstantServiceObserver and push out updates that | 205 // register itself as an InstantServiceObserver and push out updates that |
| 270 // way. Refer to crbug.com/246355 for more details. | 206 // way. Refer to crbug.com/246355 for more details. |
| 271 controller->UpdateMostVisitedItems(); | 207 controller->UpdateMostVisitedItems(); |
| 272 } | 208 } |
| 273 #endif | 209 #endif |
| 274 } | 210 } |
| OLD | NEW |