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 |