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_url_tracker_navigation_helper_impl.h"
7 #include "chrome/browser/chrome_notification_types.h"
8 #include "chrome/browser/google/google_url_tracker.h"
9 #include "chrome/browser/infobars/infobar_service.h"
10 #include "content/public/browser/navigation_controller.h"
11 #include "content/public/browser/navigation_entry.h"
12 #include "content/public/browser/notification_service.h"
13 #include "content/public/browser/web_contents.h"
15 GoogleURLTrackerNavigationHelperImpl::
16 GoogleURLTrackerNavigationHelperImpl() : tracker_(NULL
) {
19 GoogleURLTrackerNavigationHelperImpl::
20 ~GoogleURLTrackerNavigationHelperImpl() {
23 void GoogleURLTrackerNavigationHelperImpl::SetGoogleURLTracker(
24 GoogleURLTracker
* tracker
) {
29 void GoogleURLTrackerNavigationHelperImpl::SetListeningForNavigationStart(
32 registrar_
.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING
,
33 content::NotificationService::AllBrowserContextsAndSources());
35 registrar_
.Remove(this, content::NOTIFICATION_NAV_ENTRY_PENDING
,
36 content::NotificationService::AllBrowserContextsAndSources());
40 bool GoogleURLTrackerNavigationHelperImpl::IsListeningForNavigationStart() {
41 return registrar_
.IsRegistered(this, content::NOTIFICATION_NAV_ENTRY_PENDING
,
42 content::NotificationService::AllBrowserContextsAndSources());
45 void GoogleURLTrackerNavigationHelperImpl::SetListeningForNavigationCommit(
46 const content::NavigationController
* nav_controller
,
48 content::NotificationSource navigation_controller_source
=
49 content::Source
<content::NavigationController
>(nav_controller
);
51 registrar_
.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
52 navigation_controller_source
);
54 registrar_
.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
55 navigation_controller_source
);
59 bool GoogleURLTrackerNavigationHelperImpl::IsListeningForNavigationCommit(
60 const content::NavigationController
* nav_controller
) {
61 content::NotificationSource navigation_controller_source
=
62 content::Source
<content::NavigationController
>(nav_controller
);
63 return registrar_
.IsRegistered(
64 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
65 navigation_controller_source
);
68 void GoogleURLTrackerNavigationHelperImpl::SetListeningForTabDestruction(
69 const content::NavigationController
* nav_controller
,
71 content::NotificationSource navigation_controller_source
=
72 content::Source
<content::NavigationController
>(nav_controller
);
74 registrar_
.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED
,
75 GetWebContentsSource(navigation_controller_source
));
77 registrar_
.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED
,
78 GetWebContentsSource(navigation_controller_source
));
82 bool GoogleURLTrackerNavigationHelperImpl::IsListeningForTabDestruction(
83 const content::NavigationController
* nav_controller
) {
84 content::NotificationSource navigation_controller_source
=
85 content::Source
<content::NavigationController
>(nav_controller
);
86 return registrar_
.IsRegistered(
88 content::NOTIFICATION_WEB_CONTENTS_DESTROYED
,
89 GetWebContentsSource(navigation_controller_source
));
92 content::NotificationSource
93 GoogleURLTrackerNavigationHelperImpl::GetWebContentsSource(
94 const content::NotificationSource
& nav_controller_source
) {
95 content::NavigationController
* controller
=
96 content::Source
<content::NavigationController
>(
97 nav_controller_source
).ptr();
98 content::WebContents
* web_contents
= controller
->GetWebContents();
99 return content::Source
<content::WebContents
>(web_contents
);
102 void GoogleURLTrackerNavigationHelperImpl::Observe(
104 const content::NotificationSource
& source
,
105 const content::NotificationDetails
& details
) {
107 case content::NOTIFICATION_NAV_ENTRY_PENDING
: {
108 content::NavigationController
* controller
=
109 content::Source
<content::NavigationController
>(source
).ptr();
110 content::WebContents
* web_contents
= controller
->GetWebContents();
111 InfoBarService
* infobar_service
=
112 InfoBarService::FromWebContents(web_contents
);
113 // Because we're listening to all sources, there may be no
114 // InfoBarService for some notifications, e.g. navigations in
115 // bubbles/balloons etc.
116 if (infobar_service
) {
117 tracker_
->OnNavigationPending(
118 controller
, infobar_service
,
119 controller
->GetPendingEntry()->GetUniqueID());
124 case content::NOTIFICATION_NAV_ENTRY_COMMITTED
: {
125 content::NavigationController
* controller
=
126 content::Source
<content::NavigationController
>(source
).ptr();
127 // Here we're only listening to notifications where we already know
128 // there's an associated InfoBarService.
129 content::WebContents
* web_contents
= controller
->GetWebContents();
130 InfoBarService
* infobar_service
=
131 InfoBarService::FromWebContents(web_contents
);
132 DCHECK(infobar_service
);
133 const GURL
& search_url
= controller
->GetActiveEntry()->GetURL();
134 if (!search_url
.is_valid()) // Not clear if this can happen.
135 tracker_
->OnTabClosed(controller
);
136 tracker_
->OnNavigationCommitted(infobar_service
, search_url
);
140 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED
: {
141 content::WebContents
* web_contents
=
142 content::Source
<content::WebContents
>(source
).ptr();
143 tracker_
->OnTabClosed(&web_contents
->GetController());
148 NOTREACHED() << "Unknown notification received:" << type
;