| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/search/search_terms_tracker.h" | |
| 6 | |
| 7 #include "chrome/browser/profiles/profile.h" | |
| 8 #include "chrome/browser/search_engines/template_url_service_factory.h" | |
| 9 #include "components/search_engines/template_url.h" | |
| 10 #include "components/search_engines/template_url_service.h" | |
| 11 #include "content/public/browser/navigation_controller.h" | |
| 12 #include "content/public/browser/navigation_entry.h" | |
| 13 #include "content/public/browser/notification_details.h" | |
| 14 #include "content/public/browser/notification_service.h" | |
| 15 #include "content/public/browser/notification_source.h" | |
| 16 #include "content/public/browser/notification_types.h" | |
| 17 #include "content/public/browser/web_contents.h" | |
| 18 | |
| 19 namespace chrome { | |
| 20 | |
| 21 SearchTermsTracker::SearchTermsTracker() { | |
| 22 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | |
| 23 content::NotificationService::AllSources()); | |
| 24 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED, | |
| 25 content::NotificationService::AllSources()); | |
| 26 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | |
| 27 content::NotificationService::AllSources()); | |
| 28 } | |
| 29 | |
| 30 SearchTermsTracker::~SearchTermsTracker() { | |
| 31 } | |
| 32 | |
| 33 bool SearchTermsTracker::GetSearchTerms( | |
| 34 const content::WebContents* contents, | |
| 35 base::string16* search_terms, | |
| 36 int* navigation_index) const { | |
| 37 if (contents) { | |
| 38 TabState::const_iterator it = tabs_.find(contents); | |
| 39 if (it != tabs_.end() && !it->second.search_terms.empty()) { | |
| 40 if (search_terms) | |
| 41 *search_terms = it->second.search_terms; | |
| 42 if (navigation_index) | |
| 43 *navigation_index = it->second.srp_navigation_index; | |
| 44 return true; | |
| 45 } | |
| 46 } | |
| 47 return false; | |
| 48 } | |
| 49 | |
| 50 void SearchTermsTracker::Observe( | |
| 51 int type, | |
| 52 const content::NotificationSource& source, | |
| 53 const content::NotificationDetails& details) { | |
| 54 switch (type) { | |
| 55 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: | |
| 56 case content::NOTIFICATION_NAV_ENTRY_CHANGED: { | |
| 57 content::NavigationController* controller = | |
| 58 content::Source<content::NavigationController>(source).ptr(); | |
| 59 TabData search; | |
| 60 if (FindMostRecentSearch(controller, &search)) | |
| 61 tabs_[controller->GetWebContents()] = search; | |
| 62 else | |
| 63 RemoveTabData(controller->GetWebContents()); | |
| 64 break; | |
| 65 } | |
| 66 | |
| 67 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { | |
| 68 RemoveTabData(content::Source<content::WebContents>(source).ptr()); | |
| 69 break; | |
| 70 } | |
| 71 | |
| 72 default: | |
| 73 NOTREACHED(); | |
| 74 return; | |
| 75 } | |
| 76 } | |
| 77 | |
| 78 bool SearchTermsTracker::FindMostRecentSearch( | |
| 79 const content::NavigationController* controller, | |
| 80 SearchTermsTracker::TabData* tab_data) { | |
| 81 Profile* profile = | |
| 82 Profile::FromBrowserContext(controller->GetBrowserContext()); | |
| 83 DCHECK(profile); | |
| 84 if (!profile) | |
| 85 return false; | |
| 86 | |
| 87 TemplateURLService* service = | |
| 88 TemplateURLServiceFactory::GetForProfile(profile); | |
| 89 TemplateURL* template_url = service->GetDefaultSearchProvider(); | |
| 90 | |
| 91 for (int i = controller->GetCurrentEntryIndex(); i >= 0; --i) { | |
| 92 content::NavigationEntry* entry = controller->GetEntryAtIndex(i); | |
| 93 if (entry->GetPageType() == content::PAGE_TYPE_NORMAL) { | |
| 94 if (template_url->IsSearchURL(entry->GetURL(), | |
| 95 service->search_terms_data())) { | |
| 96 // This entry is a search results page. Extract the terms only if this | |
| 97 // isn't the last (i.e. most recent/current) entry as we don't want to | |
| 98 // record the search terms when we're on an SRP. | |
| 99 if (i != controller->GetCurrentEntryIndex()) { | |
| 100 tab_data->srp_navigation_index = i; | |
| 101 template_url->ExtractSearchTermsFromURL(entry->GetURL(), | |
| 102 service->search_terms_data(), | |
| 103 &tab_data->search_terms); | |
| 104 return true; | |
| 105 } | |
| 106 | |
| 107 // We've found an SRP - stop searching (even if we did not record the | |
| 108 // search terms, as anything before this entry will be unrelated). | |
| 109 break; | |
| 110 } | |
| 111 } | |
| 112 | |
| 113 // Do not consider any navigations that precede a non-web-triggerable | |
| 114 // navigation as they are not related to those terms. | |
| 115 if (!ui::PageTransitionIsWebTriggerable( | |
| 116 entry->GetTransitionType())) { | |
| 117 break; | |
| 118 } | |
| 119 } | |
| 120 | |
| 121 return false; | |
| 122 } | |
| 123 | |
| 124 void SearchTermsTracker::RemoveTabData( | |
| 125 const content::WebContents* contents) { | |
| 126 TabState::iterator it = tabs_.find(contents); | |
| 127 if (it != tabs_.end()) { | |
| 128 tabs_.erase(it); | |
| 129 } | |
| 130 } | |
| 131 | |
| 132 } // namespace chrome | |
| OLD | NEW |