diff options
author | kmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-08 05:13:36 +0000 |
---|---|---|
committer | kmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-08 05:13:36 +0000 |
commit | ab01dd75463270917a517f2a554e7fe91c1d6a43 (patch) | |
tree | 37939d8f274793fc990f07c789950c77d95190a4 | |
parent | 18d7de1508fda349cf0cc88bb5e5d200f6c238bd (diff) | |
download | chromium_src-ab01dd75463270917a517f2a554e7fe91c1d6a43.zip chromium_src-ab01dd75463270917a517f2a554e7fe91c1d6a43.tar.gz chromium_src-ab01dd75463270917a517f2a554e7fe91c1d6a43.tar.bz2 |
Rip out browser-side RID caching for most visited items.
(1) Most visited thumbnails and favicons no longer require id-based urls. Updated ThumbnailSource and FaviconSource to serve requests of the form:
chrome-search://favicon/<most_visited_item_favicon_url>
chrome-search://thumb/<most_visited_item_thumbnail_url>
(2) Removed |most_visited_items_cache_| from InstantIOContext and InstantService.
(3) SearchTabHelper will track the last sent most visited items. This prevents duplicate most visited item related IPCs while switching tabs.
BUG=239253, 225760, 242667
TEST=none
Review URL: https://chromiumcodereview.appspot.com/15907006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@205026 0039d316-1c4b-4281-b951-d872f2087c98
24 files changed, 275 insertions, 284 deletions
diff --git a/chrome/browser/search/instant_io_context.cc b/chrome/browser/search/instant_io_context.cc index ff70801..c579f969 100644 --- a/chrome/browser/search/instant_io_context.cc +++ b/chrome/browser/search/instant_io_context.cc @@ -35,8 +35,7 @@ InstantIOContext* GetDataForRequest(const net::URLRequest* request) { const char InstantIOContext::kInstantIOContextKeyName[] = "instant_io_context"; -InstantIOContext::InstantIOContext() - : most_visited_item_cache_(kMaxInstantMostVisitedItemCacheSize) { +InstantIOContext::InstantIOContext() { // The InstantIOContext is created on the UI thread but is accessed // on the IO thread. DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); @@ -77,15 +76,6 @@ void InstantIOContext::ClearInstantProcessesOnIO( } // static -void InstantIOContext::AddMostVisitedItemsOnIO( - scoped_refptr<InstantIOContext> instant_io_context, - std::vector<InstantMostVisitedItemIDPair> items) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - instant_io_context->most_visited_item_cache_.AddItemsWithRestrictedID(items); -} - - -// static bool InstantIOContext::ShouldServiceRequest(const net::URLRequest* request) { const content::ResourceRequestInfo* info = content::ResourceRequestInfo::ForRequest(request); @@ -104,36 +94,7 @@ bool InstantIOContext::ShouldServiceRequest(const net::URLRequest* request) { return false; } -// static -bool InstantIOContext::GetURLForMostVisitedItemID( - const net::URLRequest* request, - InstantRestrictedID most_visited_item_id, - GURL* url) { - InstantIOContext* instant_io_context = GetDataForRequest(request); - if (!instant_io_context) { - *url = GURL(); - return false; - } - - return instant_io_context->GetURLForMostVisitedItemID(most_visited_item_id, - url); -} - bool InstantIOContext::IsInstantProcess(int process_id) const { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); return process_ids_.find(process_id) != process_ids_.end(); } - -bool InstantIOContext::GetURLForMostVisitedItemID( - InstantRestrictedID most_visited_item_id, - GURL* url) const { - InstantMostVisitedItem item; - if (most_visited_item_cache_.GetItemWithRestrictedID(most_visited_item_id, - &item)) { - *url = item.url; - return true; - } - - *url = GURL(); - return false; -} diff --git a/chrome/browser/search/instant_io_context.h b/chrome/browser/search/instant_io_context.h index d061fa88..325a395 100644 --- a/chrome/browser/search/instant_io_context.h +++ b/chrome/browser/search/instant_io_context.h @@ -5,13 +5,10 @@ #ifndef CHROME_BROWSER_SEARCH_INSTANT_IO_CONTEXT_H_ #define CHROME_BROWSER_SEARCH_INSTANT_IO_CONTEXT_H_ -#include <map> #include <set> -#include <vector> #include "base/basictypes.h" #include "base/memory/ref_counted.h" -#include "chrome/common/instant_restricted_id_cache.h" class GURL; @@ -51,22 +48,10 @@ class InstantIOContext : public base::RefCountedThreadSafe<InstantIOContext> { static void ClearInstantProcessesOnIO( scoped_refptr<InstantIOContext> instant_io_context); - // Associates the |most_visited_item_id| with the |url|. - static void AddMostVisitedItemsOnIO( - scoped_refptr<InstantIOContext> instant_io_context, - std::vector<InstantMostVisitedItemIDPair> items); - // Determine if this chrome-search: request is coming from an Instant render // process. static bool ShouldServiceRequest(const net::URLRequest* request); - // If there is a mapping for the |most_visited_item_id|, sets |url| and - // returns true. - static bool GetURLForMostVisitedItemID( - const net::URLRequest* request, - InstantRestrictedID most_visited_item_id, - GURL* url); - protected: virtual ~InstantIOContext(); @@ -77,18 +62,11 @@ class InstantIOContext : public base::RefCountedThreadSafe<InstantIOContext> { // |process_ids_|. bool IsInstantProcess(int process_id) const; - bool GetURLForMostVisitedItemID(InstantRestrictedID most_visited_item_id, - GURL* url) const; - // The process IDs associated with Instant processes. Mirror of the process // IDs in InstantService. Duplicated here for synchronous access on the IO // thread. std::set<int> process_ids_; - // The Most Visited item cache. Mirror of the Most Visited item cache in - // InstantService. Duplicated here for synchronous access on the IO thread. - InstantRestrictedIDCache<InstantMostVisitedItem> most_visited_item_cache_; - DISALLOW_COPY_AND_ASSIGN(InstantIOContext); }; diff --git a/chrome/browser/search/instant_service.cc b/chrome/browser/search/instant_service.cc index b1e4ebd..ccf8c88 100644 --- a/chrome/browser/search/instant_service.cc +++ b/chrome/browser/search/instant_service.cc @@ -16,6 +16,7 @@ #include "chrome/browser/search/instant_service_factory.h" #include "chrome/browser/search/local_ntp_source.h" #include "chrome/browser/search/most_visited_iframe_source.h" +#include "chrome/browser/search/search.h" #include "chrome/browser/search/suggestion_iframe_source.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_instant_controller.h" @@ -38,7 +39,6 @@ using content::BrowserThread; InstantService::InstantService(Profile* profile) : profile_(profile), - most_visited_item_cache_(kMaxInstantMostVisitedItemCacheSize), weak_ptr_factory_(this) { // Stub for unit tests. if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) @@ -78,52 +78,6 @@ InstantService::InstantService(Profile* profile) InstantService::~InstantService() { } -// static -const std::string InstantService::MaybeTranslateInstantPathOnUI( - Profile* profile, const std::string& path) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - InstantService* instant_service = - InstantServiceFactory::GetForProfile(profile); - if (!instant_service) - return path; - - InstantRestrictedID restricted_id = 0; - DCHECK_EQ(sizeof(InstantRestrictedID), sizeof(int)); - if (base::StringToInt(path, &restricted_id)) { - InstantMostVisitedItem item; - if (instant_service->GetMostVisitedItemForID(restricted_id, &item)) - return item.url.spec(); - } - return path; -} - -const std::string InstantService::MaybeTranslateInstantPathOnIO( - const net::URLRequest* request, const std::string& path) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - - InstantRestrictedID restricted_id = 0; - DCHECK_EQ(sizeof(InstantRestrictedID), sizeof(int)); - if (base::StringToInt(path, &restricted_id)) { - GURL url; - if (InstantIOContext::GetURLForMostVisitedItemID(request, - restricted_id, - &url)) { - return url.spec(); - } - } - return path; -} - -// static -bool InstantService::IsInstantPath(const GURL& url) { - // Strip leading slash. - std::string path = url.path().substr(1); - - // Check that path is of Most Visited item ID form. - InstantRestrictedID dummy = 0; - return base::StringToInt(path, &dummy); -} - void InstantService::AddInstantProcess(int process_id) { process_ids_.insert(process_id); @@ -140,22 +94,6 @@ bool InstantService::IsInstantProcess(int process_id) const { return process_ids_.find(process_id) != process_ids_.end(); } -void InstantService::AddMostVisitedItems( - const std::vector<InstantMostVisitedItem>& items) { - most_visited_item_cache_.AddItems(items); - - // Post task to the IO thread to copy the data. - if (instant_io_context_.get()) { - std::vector<InstantMostVisitedItemIDPair> items; - most_visited_item_cache_.GetCurrentItems(&items); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::Bind(&InstantIOContext::AddMostVisitedItemsOnIO, - instant_io_context_, - items)); - } -} - void InstantService::DeleteMostVisitedItem(const GURL& url) { history::TopSites* top_sites = profile_->GetTopSites(); if (!top_sites) @@ -181,8 +119,8 @@ void InstantService::UndoAllMostVisitedDeletions() { } void InstantService::GetCurrentMostVisitedItems( - std::vector<InstantMostVisitedItemIDPair>* items) const { - most_visited_item_cache_.GetCurrentItems(items); + std::vector<InstantMostVisitedItem>* items) const { + *items = most_visited_items_; } void InstantService::Shutdown() { @@ -231,13 +169,6 @@ void InstantService::Observe(int type, } } -bool InstantService::GetMostVisitedItemForID( - InstantRestrictedID most_visited_item_id, - InstantMostVisitedItem* item) const { - return most_visited_item_cache_.GetItemWithRestrictedID( - most_visited_item_id, item); -} - void InstantService::OnMostVisitedItemsReceived( const history::MostVisitedURLList& data) { // Android doesn't use Browser/BrowserList. Do nothing for Android platform. @@ -245,15 +176,20 @@ void InstantService::OnMostVisitedItemsReceived( history::MostVisitedURLList reordered_data(data); history::TopSites::MaybeShuffle(&reordered_data); - std::vector<InstantMostVisitedItem> most_visited_items; + std::vector<InstantMostVisitedItem> new_most_visited_items; for (size_t i = 0; i < reordered_data.size(); i++) { const history::MostVisitedURL& url = reordered_data[i]; InstantMostVisitedItem item; item.url = url.url; item.title = url.title; - most_visited_items.push_back(item); + new_most_visited_items.push_back(item); } - AddMostVisitedItems(most_visited_items); + if (chrome::AreMostVisitedItemsEqual(new_most_visited_items, + most_visited_items_)) { + return; + } + + most_visited_items_ = new_most_visited_items; const BrowserList* browser_list = BrowserList::GetInstance(chrome::GetActiveDesktop()); diff --git a/chrome/browser/search/instant_service.h b/chrome/browser/search/instant_service.h index 8bd6cbd..4832ded 100644 --- a/chrome/browser/search/instant_service.h +++ b/chrome/browser/search/instant_service.h @@ -8,13 +8,14 @@ #include <map> #include <set> #include <string> +#include <vector> #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/history/history_types.h" -#include "chrome/common/instant_restricted_id_cache.h" +#include "chrome/common/instant_types.h" #include "components/browser_context_keyed_service/browser_context_keyed_service.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -34,19 +35,6 @@ class InstantService : public BrowserContextKeyedService, explicit InstantService(Profile* profile); virtual ~InstantService(); - // A utility to translate an Instant path if it is of Most Visited item ID - // form. If path is a Most Visited item ID and we have a URL for it, then - // this URL is returned in string form. The |path| is a URL fragment - // corresponding to the path of url with the leading slash ("/") stripped. - // For example, chrome-search://favicon/72 would yield a |path| value of "72", - // and since 72 is a valid uint64 the path is translated to a valid url, - // "http://bingo.com/", say. - static const std::string MaybeTranslateInstantPathOnUI( - Profile* profile, const std::string& path); - static const std::string MaybeTranslateInstantPathOnIO( - const net::URLRequest* request, const std::string& path); - static bool IsInstantPath(const GURL& url); - // Add, remove, and query RenderProcessHost IDs that are associated with // Instant processes. void AddInstantProcess(int process_id); @@ -60,10 +48,6 @@ class InstantService : public BrowserContextKeyedService, // Most visited item API. - // Adds |items| to the |most_visited_item_cache_| assigning restricted IDs in - // the process. - void AddMostVisitedItems(const std::vector<InstantMostVisitedItem>& items); - // Invoked by the InstantController when the Instant page wants to delete a // Most Visited item. void DeleteMostVisitedItem(const GURL& url); @@ -76,11 +60,9 @@ class InstantService : public BrowserContextKeyedService, // Most Visited deletions. void UndoAllMostVisitedDeletions(); - // Returns the last added InstantMostVisitedItems. After the call to - // |AddMostVisitedItems|, the caller should call this to get the items with - // the assigned IDs. + // Returns the last added InstantMostVisitedItems. void GetCurrentMostVisitedItems( - std::vector<InstantMostVisitedItemIDPair>* items) const; + std::vector<InstantMostVisitedItem>* items) const; private: // Overridden from BrowserContextKeyedService: @@ -91,11 +73,6 @@ class InstantService : public BrowserContextKeyedService, const content::NotificationSource& source, const content::NotificationDetails& details) OVERRIDE; - // If the |most_visited_item_id| is found in the cache, sets the |item| to it - // and returns true. - bool GetMostVisitedItemForID(InstantRestrictedID most_visited_item_id, - InstantMostVisitedItem* item) const; - // Called when we get new most visited items from TopSites, registered as an // async callback. Parses them and sends them to the renderer via // SendMostVisitedItems. @@ -106,8 +83,8 @@ class InstantService : public BrowserContextKeyedService, // The process ids associated with Instant processes. std::set<int> process_ids_; - // A cache of the InstantMostVisitedItems sent to the Instant Pages. - InstantRestrictedIDCache<InstantMostVisitedItem> most_visited_item_cache_; + // InstantMostVisitedItems sent to the Instant Pages. + std::vector<InstantMostVisitedItem> most_visited_items_; content::NotificationRegistrar registrar_; diff --git a/chrome/browser/search/search.cc b/chrome/browser/search/search.cc index d8a4fb1..50b5634 100644 --- a/chrome/browser/search/search.cc +++ b/chrome/browser/search/search.cc @@ -740,4 +740,19 @@ void ResetInstantExtendedOptInStateGateForTest() { instant_extended_opt_in_state_gate = false; } +bool AreMostVisitedItemsEqual( + const std::vector<InstantMostVisitedItem>& items_a, + const std::vector<InstantMostVisitedItem>& items_b) { + if (items_a.size() != items_b.size()) + return false; + + for (size_t i = 0; i < items_b.size(); ++i) { + if (items_b[i].url != items_a[i].url || + items_b[i].title != items_a[i].title) { + return false; + } + } + return true; +} + } // namespace chrome diff --git a/chrome/browser/search/search.h b/chrome/browser/search/search.h index 8d83e3a..aa6f851 100644 --- a/chrome/browser/search/search.h +++ b/chrome/browser/search/search.h @@ -11,6 +11,7 @@ #include "base/basictypes.h" #include "base/string16.h" +#include "chrome/common/instant_types.h" class GURL; class Profile; @@ -231,6 +232,11 @@ bool DefaultSearchProviderSupportsInstant(Profile* profile); // once. void ResetInstantExtendedOptInStateGateForTest(); +// Returns true if |items_a| and |items_b| are equal. +bool AreMostVisitedItemsEqual( + const std::vector<InstantMostVisitedItem>& items_a, + const std::vector<InstantMostVisitedItem>& items_b); + } // namespace chrome #endif // CHROME_BROWSER_SEARCH_SEARCH_H_ diff --git a/chrome/browser/ui/search/instant_controller.cc b/chrome/browser/ui/search/instant_controller.cc index 4e93098..fe8aae9 100644 --- a/chrome/browser/ui/search/instant_controller.cc +++ b/chrome/browser/ui/search/instant_controller.cc @@ -1122,15 +1122,26 @@ void InstantController::UpdateMostVisitedItems() { if (!instant_service) return; - std::vector<InstantMostVisitedItemIDPair> items; + std::vector<InstantMostVisitedItem> items; instant_service->GetCurrentMostVisitedItems(&items); - if (overlay_) + if (overlay_ && GetOverlayContents() && + SearchTabHelper::FromWebContents(overlay_->contents())-> + UpdateLastKnownMostVisitedItems(items)) { overlay_->SendMostVisitedItems(items); - if (ntp_) + } + + if (ntp_ && ntp_->contents() && + SearchTabHelper::FromWebContents(ntp_->contents())-> + UpdateLastKnownMostVisitedItems(items)) { ntp_->SendMostVisitedItems(items); - if (instant_tab_) + } + + if (instant_tab_ && instant_tab_->contents() && + SearchTabHelper::FromWebContents(instant_tab_->contents())-> + UpdateLastKnownMostVisitedItems(items)) { instant_tab_->SendMostVisitedItems(items); + } content::NotificationService::current()->Notify( chrome::NOTIFICATION_INSTANT_SENT_MOST_VISITED_ITEMS, diff --git a/chrome/browser/ui/search/instant_extended_interactive_uitest.cc b/chrome/browser/ui/search/instant_extended_interactive_uitest.cc index e0354bb..1a7ced1 100644 --- a/chrome/browser/ui/search/instant_extended_interactive_uitest.cc +++ b/chrome/browser/ui/search/instant_extended_interactive_uitest.cc @@ -1276,8 +1276,7 @@ IN_PROC_BROWSER_TEST_F(InstantExtendedTest, omnibox()->RevertAll(); } -// TODO(dhollowa): Fix flakes. http://crbug.com/179930. -IN_PROC_BROWSER_TEST_F(InstantExtendedTest, DISABLED_MostVisited) { +IN_PROC_BROWSER_TEST_F(InstantExtendedTest, MostVisited) { content::WindowedNotificationObserver observer( chrome::NOTIFICATION_INSTANT_SENT_MOST_VISITED_ITEMS, content::NotificationService::AllSources()); diff --git a/chrome/browser/ui/search/instant_page.cc b/chrome/browser/ui/search/instant_page.cc index 9b4a021..e7b587f 100644 --- a/chrome/browser/ui/search/instant_page.cc +++ b/chrome/browser/ui/search/instant_page.cc @@ -118,7 +118,7 @@ void InstantPage::FocusChanged(OmniboxFocusState state, } void InstantPage::SendMostVisitedItems( - const std::vector<InstantMostVisitedItemIDPair>& items) { + const std::vector<InstantMostVisitedItem>& items) { Send(new ChromeViewMsg_SearchBoxMostVisitedItemsChanged(routing_id(), items)); } diff --git a/chrome/browser/ui/search/instant_page.h b/chrome/browser/ui/search/instant_page.h index 56d1291..7c3d719 100644 --- a/chrome/browser/ui/search/instant_page.h +++ b/chrome/browser/ui/search/instant_page.h @@ -193,7 +193,7 @@ class InstantPage : public content::WebContentsObserver { // Tells the page about new Most Visited data. void SendMostVisitedItems( - const std::vector<InstantMostVisitedItemIDPair>& items); + const std::vector<InstantMostVisitedItem>& items); // Tells the page to toggle voice search. void ToggleVoiceSearch(); diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc index 5086f81..f84abbe 100644 --- a/chrome/browser/ui/search/search_tab_helper.cc +++ b/chrome/browser/ui/search/search_tab_helper.cc @@ -75,6 +75,15 @@ void SearchTabHelper::NavigationEntryUpdated() { UpdateMode(); } +bool SearchTabHelper::UpdateLastKnownMostVisitedItems( + const std::vector<InstantMostVisitedItem>& items) { + if (chrome::AreMostVisitedItemsEqual(items, last_known_most_visited_items_)) + return false; + + last_known_most_visited_items_ = items; + return true; +} + void SearchTabHelper::Observe( int type, const content::NotificationSource& source, diff --git a/chrome/browser/ui/search/search_tab_helper.h b/chrome/browser/ui/search/search_tab_helper.h index 7b0ff13..8dd7711 100644 --- a/chrome/browser/ui/search/search_tab_helper.h +++ b/chrome/browser/ui/search/search_tab_helper.h @@ -5,9 +5,12 @@ #ifndef CHROME_BROWSER_UI_SEARCH_SEARCH_TAB_HELPER_H_ #define CHROME_BROWSER_UI_SEARCH_SEARCH_TAB_HELPER_H_ +#include <vector> + #include "base/basictypes.h" #include "base/compiler_specific.h" #include "chrome/browser/ui/search/search_model.h" +#include "chrome/common/instant_types.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/web_contents_observer.h" @@ -42,6 +45,11 @@ class SearchTabHelper : public content::NotificationObserver, // the notification system and shouldn't call this method. void NavigationEntryUpdated(); + // Updates |last_known_most_visited_items_| with |items|. + // Returns false if |items| matches the |last_known_most_visited_items_|. + bool UpdateLastKnownMostVisitedItems( + const std::vector<InstantMostVisitedItem>& items); + private: friend class content::WebContentsUserData<SearchTabHelper>; @@ -77,6 +85,10 @@ class SearchTabHelper : public content::NotificationObserver, content::WebContents* web_contents_; + // Tracks the last set of most visited items sent to the InstantPage renderer. + // Used to prevent sending duplicate IPC messages to the renderer. + std::vector<InstantMostVisitedItem> last_known_most_visited_items_; + DISALLOW_COPY_AND_ASSIGN(SearchTabHelper); }; diff --git a/chrome/browser/ui/webui/favicon_source.cc b/chrome/browser/ui/webui/favicon_source.cc index b71df5d..4552273 100644 --- a/chrome/browser/ui/webui/favicon_source.cc +++ b/chrome/browser/ui/webui/favicon_source.cc @@ -82,7 +82,7 @@ std::string FaviconSource::GetSource() const { } void FaviconSource::StartDataRequest( - const std::string& raw_path, + const std::string& path, int render_process_id, int render_view_id, const content::URLDataSource::GotDataCallback& callback) { @@ -97,7 +97,7 @@ void FaviconSource::StartDataRequest( GURL url; int size_in_dip = 16; ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_100P; - bool success = ParsePath(raw_path, &is_icon_url, &url, &size_in_dip, + bool success = ParsePath(path, &is_icon_url, &url, &size_in_dip, &scale_factor); if (!success) { @@ -160,10 +160,8 @@ bool FaviconSource::ShouldReplaceExistingSource() const { } bool FaviconSource::ShouldServiceRequest(const net::URLRequest* request) const { - if (request->url().SchemeIs(chrome::kChromeSearchScheme)) { - return InstantService::IsInstantPath(request->url()) && - InstantIOContext::ShouldServiceRequest(request); - } + if (request->url().SchemeIs(chrome::kChromeSearchScheme)) + return InstantIOContext::ShouldServiceRequest(request); return URLDataSource::ShouldServiceRequest(request); } @@ -173,7 +171,7 @@ bool FaviconSource::HandleMissingResource(const IconRequest& request) { return false; } -bool FaviconSource::ParsePath(const std::string& raw_path, +bool FaviconSource::ParsePath(const std::string& path, bool* is_icon_url, GURL* url, int* size_in_dip, @@ -185,14 +183,9 @@ bool FaviconSource::ParsePath(const std::string& raw_path, *size_in_dip = 16; *scale_factor = ui::SCALE_FACTOR_100P; - if (raw_path.empty()) + if (path.empty()) return false; - // Translate to regular path if |raw_path| is of the form - // chrome-search://favicon/<most_visited_item_id>, where - // "most_visited_item_id" is a uint64. - std::string path = InstantService::MaybeTranslateInstantPathOnUI(profile_, - raw_path); size_t parsed_index = 0; if (HasSubstringAt(path, parsed_index, kLargestParameter)) { parsed_index += strlen(kLargestParameter); @@ -213,8 +206,7 @@ bool FaviconSource::ParsePath(const std::string& raw_path, size_str = path.substr(parsed_index, slash - parsed_index); } else { size_str = path.substr(parsed_index, scale_delimiter - parsed_index); - scale_str = path.substr(scale_delimiter + 1, - slash - scale_delimiter - 1); + scale_str = path.substr(scale_delimiter + 1, slash - scale_delimiter - 1); } if (!base::StringToInt(size_str, size_in_dip)) diff --git a/chrome/browser/ui/webui/favicon_source.h b/chrome/browser/ui/webui/favicon_source.h index b1faf72..b880374 100644 --- a/chrome/browser/ui/webui/favicon_source.h +++ b/chrome/browser/ui/webui/favicon_source.h @@ -117,9 +117,9 @@ class FaviconSource : public content::URLDataSource { NUM_SIZES }; - // Parses |raw_path|, which should be in the format described at the top of - // the file. Returns true if |raw_path| could be parsed. - bool ParsePath(const std::string& raw_path, + // Parses |path|, which should be in the format described at the top of the + // file. Returns true if |path| could be parsed. + bool ParsePath(const std::string& path, bool* is_icon_url, GURL* url, int* size_in_dip, diff --git a/chrome/browser/ui/webui/favicon_source_unittest.cc b/chrome/browser/ui/webui/favicon_source_unittest.cc index 5a854ac..2710503 100644 --- a/chrome/browser/ui/webui/favicon_source_unittest.cc +++ b/chrome/browser/ui/webui/favicon_source_unittest.cc @@ -35,23 +35,6 @@ class FaviconSourceTest : public testing::Test { virtual ~FaviconSourceTest() { } - // Adds a most visited item with |url| and an arbitrary title to the instant - // service and returns the assigned id. - int AddInstantMostVisitedUrlAndGetId(GURL url) { - InstantMostVisitedItem item; - item.url = GURL(url); - std::vector<InstantMostVisitedItem> items(1, item); - - InstantService* instant_service = - InstantServiceFactory::GetForProfile(profile_.get()); - instant_service->AddMostVisitedItems(items); - - std::vector<InstantMostVisitedItemIDPair> items_with_ids; - instant_service->GetCurrentMostVisitedItems(&items_with_ids); - CHECK_EQ(1u, items_with_ids.size()); - return items_with_ids[0].first; - } - FaviconSource* favicon_source() const { return favicon_source_.get(); } private: @@ -71,29 +54,16 @@ class FaviconSourceTest : public testing::Test { // Test parsing the chrome-search://favicon/ URLs TEST_F(FaviconSourceTest, InstantParsing) { - GURL kUrl1("http://www.google.com/"); - GURL kUrl2("http://maps.google.com/"); - int instant_id1 = AddInstantMostVisitedUrlAndGetId(kUrl1); - int instant_id2 = AddInstantMostVisitedUrlAndGetId(kUrl2); - + const std::string path("chrome-search://favicon/http://www.google.com"); bool is_icon_url; GURL url; int size_in_dip; ui::ScaleFactor scale_factor; - const std::string path1 = base::IntToString(instant_id1); - EXPECT_TRUE(favicon_source()->ParsePath(path1, &is_icon_url, &url, - &size_in_dip, &scale_factor)); - EXPECT_FALSE(is_icon_url); - EXPECT_EQ(kUrl1, url); - EXPECT_EQ(16, size_in_dip); - EXPECT_EQ(ui::SCALE_FACTOR_100P, scale_factor); - - const std::string path2 = base::IntToString(instant_id2); - EXPECT_TRUE(favicon_source()->ParsePath(path2, &is_icon_url, &url, + EXPECT_TRUE(favicon_source()->ParsePath(path, &is_icon_url, &url, &size_in_dip, &scale_factor)); EXPECT_FALSE(is_icon_url); - EXPECT_EQ(kUrl2, url); + EXPECT_EQ(GURL(path), url); EXPECT_EQ(16, size_in_dip); EXPECT_EQ(ui::SCALE_FACTOR_100P, scale_factor); } diff --git a/chrome/browser/ui/webui/ntp/thumbnail_source.cc b/chrome/browser/ui/webui/ntp/thumbnail_source.cc index 4870107..a1767d7 100644 --- a/chrome/browser/ui/webui/ntp/thumbnail_source.cc +++ b/chrome/browser/ui/webui/ntp/thumbnail_source.cc @@ -35,25 +35,10 @@ std::string ThumbnailSource::GetSource() const { } void ThumbnailSource::StartDataRequest( - const std::string& raw_path, + const std::string& path, int render_process_id, int render_view_id, const content::URLDataSource::GotDataCallback& callback) { - // Translate to regular path if |raw_path| is of the form - // chrome-search://favicon/<id> or chrome-search://thumb/<id>, where <id> is - // an integer. - std::string path = raw_path; - if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { - std::map<std::string, std::string>::iterator it = - id_to_url_map_.find(raw_path); - if (it != id_to_url_map_.end()) { - path = id_to_url_map_[raw_path]; - id_to_url_map_.erase(it); - } - } else if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { - path = InstantService::MaybeTranslateInstantPathOnUI(profile_, raw_path); - } - scoped_refptr<base::RefCountedMemory> data; if (thumbnail_service_->GetPageThumbnail(GURL(path), &data)) { // We have the thumbnail. @@ -78,22 +63,7 @@ base::MessageLoop* ThumbnailSource::MessageLoopForRequestPath( bool ThumbnailSource::ShouldServiceRequest( const net::URLRequest* request) const { - if (request->url().SchemeIs(chrome::kChromeSearchScheme)) { - if (InstantService::IsInstantPath(request->url()) && - InstantIOContext::ShouldServiceRequest(request)) { - // If this request will be serviced on the IO thread, then do the - // translation from raw_path to path here, where we have the |request| - // object in-hand, saving the result for later use. - - // Strip leading slash from path. - std::string raw_path = request->url().path().substr(1); - if (!MessageLoopForRequestPath(raw_path)) { - id_to_url_map_[raw_path] = - InstantService::MaybeTranslateInstantPathOnIO(request, raw_path); - } - return true; - } - return false; - } + if (request->url().SchemeIs(chrome::kChromeSearchScheme)) + return InstantIOContext::ShouldServiceRequest(request); return URLDataSource::ShouldServiceRequest(request); } diff --git a/chrome/browser/ui/webui/ntp/thumbnail_source.h b/chrome/browser/ui/webui/ntp/thumbnail_source.h index 09be5be..8008407 100644 --- a/chrome/browser/ui/webui/ntp/thumbnail_source.h +++ b/chrome/browser/ui/webui/ntp/thumbnail_source.h @@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_UI_WEBUI_NTP_THUMBNAIL_SOURCE_H_ #define CHROME_BROWSER_UI_WEBUI_NTP_THUMBNAIL_SOURCE_H_ -#include <map> #include <string> #include "base/basictypes.h" @@ -51,14 +50,6 @@ class ThumbnailSource : public content::URLDataSource { // ThumbnailService. scoped_refptr<thumbnails::ThumbnailService> thumbnail_service_; - // Transient mappings from an ID-based path to an URL-based path. - // The key is an ID-string, the value is a URL string. - // Mappings are added in ShouldServiceRequest() and erased once - // the request is serviced in StartDataRequest(). - // TODO(dhollowa): Consider passing the |request| object through - // to the StartDataRequest() call. - mutable std::map<std::string, std::string> id_to_url_map_; - // Only used when servicing requests on the UI thread. Profile* const profile_; diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 6d45397..65b097e 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -1702,6 +1702,7 @@ 'renderer/safe_browsing/phishing_url_feature_extractor_unittest.cc', 'renderer/safe_browsing/scorer_unittest.cc', 'renderer/searchbox/searchbox_extension_unittest.cc', + 'renderer/searchbox/searchbox_unittest.cc', 'renderer/spellchecker/custom_dictionary_engine_unittest.cc', 'renderer/spellchecker/spellcheck_provider_hunspell_unittest.cc', 'renderer/spellchecker/spellcheck_provider_mac_unittest.cc', diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 2c43b60..a54d64f 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -368,7 +368,7 @@ IPC_MESSAGE_ROUTED2(ChromeViewMsg_SearchBoxFocusChanged, OmniboxFocusChangeReason /* reason */) IPC_MESSAGE_ROUTED1(ChromeViewMsg_SearchBoxMostVisitedItemsChanged, - std::vector<InstantMostVisitedItemIDPair> /* items */) + std::vector<InstantMostVisitedItem> /* items */) IPC_MESSAGE_ROUTED1(ChromeViewHostMsg_SearchBoxDeleteMostVisitedItem, GURL /* url */) diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 8453972..2b61ebe 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc @@ -9,6 +9,7 @@ #include "base/metrics/histogram.h" #include "base/path_service.h" #include "base/string_util.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "chrome/common/child_process_logging.h" @@ -992,6 +993,16 @@ bool ChromeContentRendererClient::WillSendRequest( return true; } + const content::RenderView* render_view = + content::RenderView::FromWebView(frame->view()); + SearchBox* search_box = SearchBox::Get(render_view); + if (search_box && url.SchemeIs(chrome::kChromeSearchScheme)) { + if (url.host() == chrome::kChromeUIThumbnailHost) + return search_box->GenerateThumbnailURLFromTransientURL(url, new_url); + else if (url.host() == chrome::kChromeUIFaviconHost) + return search_box->GenerateFaviconURLFromTransientURL(url, new_url); + } + return false; } diff --git a/chrome/renderer/searchbox/searchbox.cc b/chrome/renderer/searchbox/searchbox.cc index c7e1362..8e1121c 100644 --- a/chrome/renderer/searchbox/searchbox.cc +++ b/chrome/renderer/searchbox/searchbox.cc @@ -4,7 +4,10 @@ #include "chrome/renderer/searchbox/searchbox.h" +#include <string> + #include "base/string_number_conversions.h" +#include "base/string_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/omnibox_focus_state.h" @@ -12,6 +15,7 @@ #include "chrome/common/url_constants.h" #include "chrome/renderer/searchbox/searchbox_extension.h" #include "content/public/renderer/render_view.h" +#include "googleurl/src/gurl.h" #include "grit/renderer_resources.h" #include "net/base/escape.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" @@ -26,6 +30,36 @@ const size_t kMaxInstantAutocompleteResultItemCacheSize = 100; } // namespace +namespace internal { // for testing + +// Parses |url| and fills in |id| with the InstantRestrictedID obtained from the +// |url|. |render_view_id| is the ID of the associated RenderView. +// +// Valid |url| forms: +// chrome-search://favicon/<view_id>/<restricted_id> +// chrome-search://thumb/<view_id>/<restricted_id> +// +// If the |url| is valid, returns true and fills in |id| with restricted_id +// value. If the |url| is invalid, returns false and |id| is not set. +bool GetInstantRestrictedIDFromURL(int render_view_id, + const GURL& url, + InstantRestrictedID* id) { + // Strip leading path. + std::string path = url.path().substr(1); + + // Check that the path is of Most visited item ID form. + std::vector<std::string> tokens; + if (Tokenize(path, "/", &tokens) != 2) + return false; + + int view_id = 0; + if (!base::StringToInt(tokens[0], &view_id) || view_id != render_view_id) + return false; + return base::StringToInt(tokens[1], id); +} + +} // namespace internal + SearchBox::SearchBox(content::RenderView* render_view) : content::RenderViewObserver(render_view), content::RenderViewObserverTracker<SearchBox>(render_view), @@ -155,6 +189,38 @@ const ThemeBackgroundInfo& SearchBox::GetThemeBackgroundInfo() { return theme_info_; } +bool SearchBox::GenerateThumbnailURLFromTransientURL(const GURL& transient_url, + GURL* url) const { + InstantRestrictedID rid = 0; + if (!internal::GetInstantRestrictedIDFromURL(render_view()->GetRoutingID(), + transient_url, &rid)) { + return false; + } + + GURL most_visited_item_url(GetURLForMostVisitedItem(rid)); + if (most_visited_item_url.is_empty()) + return false; + *url = GURL(base::StringPrintf("chrome-search://thumb/%s", + most_visited_item_url.spec().c_str())); + return true; +} + +bool SearchBox::GenerateFaviconURLFromTransientURL(const GURL& transient_url, + GURL* url) const { + InstantRestrictedID rid = 0; + if (!internal::GetInstantRestrictedIDFromURL(render_view()->GetRoutingID(), + transient_url, &rid)) { + return false; + } + + GURL most_visited_item_url(GetURLForMostVisitedItem(rid)); + if (most_visited_item_url.is_empty()) + return false; + *url = GURL(base::StringPrintf("chrome-search://favicon/%s", + most_visited_item_url.spec().c_str())); + return true; +} + bool SearchBox::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(SearchBox, message) @@ -407,9 +473,8 @@ void SearchBox::SetQuery(const string16& query, bool verbatim) { } void SearchBox::OnMostVisitedChanged( - const std::vector<InstantMostVisitedItemIDPair>& items) { - most_visited_items_cache_.AddItemsWithRestrictedID(items); - + const std::vector<InstantMostVisitedItem>& items) { + most_visited_items_cache_.AddItems(items); if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame()) { extensions_v8::SearchBoxExtension::DispatchMostVisitedChanged( render_view()->GetWebView()->mainFrame()); diff --git a/chrome/renderer/searchbox/searchbox.h b/chrome/renderer/searchbox/searchbox.h index 21ff065..49c31eb 100644 --- a/chrome/renderer/searchbox/searchbox.h +++ b/chrome/renderer/searchbox/searchbox.h @@ -114,6 +114,26 @@ class SearchBox : public content::RenderViewObserver, // browser. void UndoAllMostVisitedDeletions(); + // Generates the thumbnail URL of the most visited item specified by the + // |transient_url|. If the |transient_url| is valid, returns true and fills in + // |url|. If the |transient_url| is invalid, returns false and |url| is not + // set. + // + // Valid form of |transient_url|: + // chrome-search://thumb/<render_view_id>/<most_visited_item_id> + bool GenerateThumbnailURLFromTransientURL(const GURL& transient_url, + GURL* url) const; + + // Generates the favicon URL of the most visited item specified by the + // |transient_url|. If the |transient_url| is valid, returns true and fills in + // |url|. If the |transient_url| is invalid, returns false and |url| is not + // set. + // + // Valid form of |transient_url|: + // chrome-search://favicon/<render_view_id>/<most_visited_item_id> + bool GenerateFaviconURLFromTransientURL(const GURL& transient_url, + GURL* url) const; + private: // Overridden from content::RenderViewObserver: virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; @@ -144,7 +164,7 @@ class SearchBox : public content::RenderViewObserver, void OnFontInformationReceived(const string16& omnibox_font, size_t omnibox_font_size); void OnMostVisitedChanged( - const std::vector<InstantMostVisitedItemIDPair>& items); + const std::vector<InstantMostVisitedItem>& items); void OnToggleVoiceSearch(); // Returns the current zoom factor of the render view or 1 on failure. diff --git a/chrome/renderer/searchbox/searchbox_extension.cc b/chrome/renderer/searchbox/searchbox_extension.cc index a5bcc40..285390e 100644 --- a/chrome/renderer/searchbox/searchbox_extension.cc +++ b/chrome/renderer/searchbox/searchbox_extension.cc @@ -85,16 +85,20 @@ void Dispatch(WebKit::WebFrame* frame, const WebKit::WebString& script) { frame->executeScript(WebKit::WebScriptSource(script)); } -v8::Handle<v8::String> GenerateThumbnailURL(uint64 most_visited_item_id) { - return UTF8ToV8String( - base::StringPrintf("chrome-search://thumb/%s", - base::Uint64ToString(most_visited_item_id).c_str())); +v8::Handle<v8::String> GenerateThumbnailURL( + int render_view_id, + InstantRestrictedID most_visited_item_id) { + return UTF8ToV8String(base::StringPrintf("chrome-search://thumb/%d/%d", + render_view_id, + most_visited_item_id)); } -v8::Handle<v8::String> GenerateFaviconURL(uint64 most_visited_item_id) { - return UTF8ToV8String( - base::StringPrintf("chrome-search://favicon/%s", - base::Uint64ToString(most_visited_item_id).c_str())); +v8::Handle<v8::String> GenerateFaviconURL( + int render_view_id, + InstantRestrictedID most_visited_item_id) { + return UTF8ToV8String(base::StringPrintf("chrome-search://favicon/%d/%d", + render_view_id, + most_visited_item_id)); } // If |url| starts with |prefix|, removes |prefix|. @@ -171,6 +175,7 @@ v8::Handle<v8::Object> GenerateNativeSuggestion( // not be returned to the Instant page. These should be erased before returning // the object. See GetMostVisitedItemsWrapper() in searchbox_api.js. v8::Handle<v8::Object> GenerateMostVisitedItem( + int render_view_id, InstantRestrictedID restricted_id, const InstantMostVisitedItem &mv_item) { // We set the "dir" attribute of the title, so that in RTL locales, a LTR @@ -197,9 +202,9 @@ v8::Handle<v8::Object> GenerateMostVisitedItem( v8::Handle<v8::Object> obj = v8::Object::New(); obj->Set(v8::String::New("rid"), v8::Int32::New(restricted_id)); obj->Set(v8::String::New("thumbnailUrl"), - GenerateThumbnailURL(restricted_id)); + GenerateThumbnailURL(render_view_id, restricted_id)); obj->Set(v8::String::New("faviconUrl"), - GenerateFaviconURL(restricted_id)); + GenerateFaviconURL(render_view_id, restricted_id)); obj->Set(v8::String::New("title"), UTF16ToV8String(title)); obj->Set(v8::String::New("domain"), UTF8ToV8String(mv_item.url.host())); obj->Set(v8::String::New("direction"), UTF8ToV8String(direction)); @@ -1259,7 +1264,8 @@ v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetMostVisitedItems( search_box->GetMostVisitedItems(&instant_mv_items); v8::Handle<v8::Array> v8_mv_items = v8::Array::New(instant_mv_items.size()); for (size_t i = 0; i < instant_mv_items.size(); ++i) { - v8_mv_items->Set(i, GenerateMostVisitedItem(instant_mv_items[i].first, + v8_mv_items->Set(i, GenerateMostVisitedItem(render_view->GetRoutingID(), + instant_mv_items[i].first, instant_mv_items[i].second)); } return v8_mv_items; @@ -1408,7 +1414,8 @@ v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetMostVisitedItemData( restricted_id, &mv_item)) { return v8::Undefined(); } - return GenerateMostVisitedItem(restricted_id, mv_item); + return GenerateMostVisitedItem(render_view->GetRoutingID(), restricted_id, + mv_item); } // static diff --git a/chrome/renderer/searchbox/searchbox_unittest.cc b/chrome/renderer/searchbox/searchbox_unittest.cc new file mode 100644 index 0000000..26dcc77 --- /dev/null +++ b/chrome/renderer/searchbox/searchbox_unittest.cc @@ -0,0 +1,60 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/basictypes.h" +#include "chrome/common/instant_types.h" +#include "googleurl/src/gurl.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace internal { + +// Defined in searchbox_extension.cc +bool GetInstantRestrictedIDFromURL(int render_view_id, + const GURL& url, + InstantRestrictedID* id); + +TEST(SearchBoxUtilTest, GetInstantRestrictedIDFromTransientURL) { + const int kInvalidRenderViewID = 920; + const int kValidRenderViewID = 1; + + const struct { + int render_view_id; + GURL transient_url; + InstantRestrictedID expected_rid; + bool expected_return_val; + } test_cases[] = { + // RenderView ID matches the view id specified in the transient url. + {kValidRenderViewID, GURL("chrome-search://favicon/1/2"), 2, true}, + {kValidRenderViewID, GURL("chrome-search://thumb/1/2"), 2, true}, + + // RenderView ID does not match the view id specified in the transient url. + {kInvalidRenderViewID, GURL("chrome-search://favicon/1/2"), 0, false}, + {kInvalidRenderViewID, GURL("chrome-search://thumb/1/2"), 0, false}, + + // Invalid transient urls. + {kValidRenderViewID, GURL("chrome-search://thumb"), 0, false}, + {kValidRenderViewID, GURL("chrome-search://thumb/"), 0, false}, + {kValidRenderViewID, GURL("chrome-search://thumb/123"), 0, false}, + {kValidRenderViewID, GURL("chrome-search://thumb/xyz"), 0, false}, + {kValidRenderViewID, GURL("chrome-search://thumb/123/"), 0, false}, + {kValidRenderViewID, GURL("chrome-search://thumb/123/xyz"), 0, false}, + {kValidRenderViewID, GURL("chrome-search://favicon"), 0, false}, + {kValidRenderViewID, GURL("chrome-search://favicon/"), 0, false}, + {kValidRenderViewID, GURL("chrome-search://favicon/123"), 0, false}, + {kValidRenderViewID, GURL("chrome-search://favicon/xyz"), 0, false}, + {kValidRenderViewID, GURL("chrome-search://favicon/123/"), 0, false}, + {kValidRenderViewID, GURL("chrome-search://favicon/123/xyz"), 0, false} + }; + + InstantRestrictedID rid = 0; + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { + bool return_val = GetInstantRestrictedIDFromURL( + test_cases[i].render_view_id, test_cases[i].transient_url, &rid); + EXPECT_EQ(test_cases[i].expected_return_val, return_val); + EXPECT_EQ(test_cases[i].expected_rid, rid); + rid = 0; + } +} + +} // namespace internal |