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.
5 #include "chrome/browser/google/google_search_counter.h"
7 #include "base/logging.h"
8 #include "components/google/core/browser/google_util.h"
9 #include "content/public/browser/navigation_controller.h"
10 #include "content/public/browser/navigation_details.h"
11 #include "content/public/browser/navigation_entry.h"
12 #include "content/public/browser/notification_service.h"
13 #include "content/public/browser/notification_types.h"
16 void GoogleSearchCounter::RegisterForNotifications() {
17 GoogleSearchCounter::GetInstance()->RegisterForNotificationsInternal();
21 GoogleSearchCounter
* GoogleSearchCounter::GetInstance() {
22 return base::Singleton
<GoogleSearchCounter
>::get();
25 GoogleSearchMetrics::AccessPoint
26 GoogleSearchCounter::GetGoogleSearchAccessPointForSearchNavEntry(
27 const content::NavigationEntry
& entry
) const {
28 DCHECK(google_util::IsGoogleSearchUrl(entry
.GetURL()));
30 // If the |entry| is FROM_ADDRESS_BAR, it comes from the omnibox; if it's
31 // GENERATED, the user was doing a search, rather than doing a navigation to a
32 // search URL (e.g. from hisotry, or pasted in).
33 if (entry
.GetTransitionType() == (ui::PAGE_TRANSITION_GENERATED
|
34 ui::PAGE_TRANSITION_FROM_ADDRESS_BAR
)) {
35 return GoogleSearchMetrics::AP_OMNIBOX
;
38 // The string "source=search_app" in the |entry| URL represents a Google
39 // search from the Google Search App.
40 if (entry
.GetURL().query().find("source=search_app") != std::string::npos
)
41 return GoogleSearchMetrics::AP_SEARCH_APP
;
43 // For all other cases that we have not yet implemented or care to measure, we
44 // log a generic "catch-all" metric.
45 return GoogleSearchMetrics::AP_OTHER
;
48 bool GoogleSearchCounter::ShouldRecordCommittedDetails(
49 const content::NotificationDetails
& details
) const {
50 const content::LoadCommittedDetails
* commit
=
51 content::Details
<content::LoadCommittedDetails
>(details
).ptr();
52 return google_util::IsGoogleSearchUrl(commit
->entry
->GetURL());
55 GoogleSearchCounter::GoogleSearchCounter()
56 : search_metrics_(new GoogleSearchMetrics
) {
59 GoogleSearchCounter::~GoogleSearchCounter() {
62 void GoogleSearchCounter::ProcessCommittedEntry(
63 const content::NotificationSource
& source
,
64 const content::NotificationDetails
& details
) {
65 // Note that GoogleSearchMetrics logs metrics through UMA, which will only
66 // transmit these counts to the server if the user has opted into sending
68 const content::LoadCommittedDetails
* commit
=
69 content::Details
<content::LoadCommittedDetails
>(details
).ptr();
70 const content::NavigationEntry
& entry
= *commit
->entry
;
71 if (ShouldRecordCommittedDetails(details
)) {
72 search_metrics_
->RecordGoogleSearch(
73 GetGoogleSearchAccessPointForSearchNavEntry(entry
));
77 void GoogleSearchCounter::SetSearchMetricsForTesting(
78 GoogleSearchMetrics
* search_metrics
) {
79 DCHECK(search_metrics
);
80 search_metrics_
.reset(search_metrics
);
83 void GoogleSearchCounter::RegisterForNotificationsInternal() {
84 // We always listen for all COMMITTED navigations from all sources, as any
85 // one of them could be a navigation of interest.
86 registrar_
.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
87 content::NotificationService::AllSources());
90 void GoogleSearchCounter::Observe(int type
,
91 const content::NotificationSource
& source
,
92 const content::NotificationDetails
& details
) {
94 case content::NOTIFICATION_NAV_ENTRY_COMMITTED
:
95 ProcessCommittedEntry(source
, details
);