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.
4
5#include "chrome/browser/google/google_url_tracker_navigation_helper_impl.h"
6
7#include "chrome/browser/chrome_notification_types.h"
8#include "chrome/browser/infobars/infobar_service.h"
9#include "components/google/core/browser/google_url_tracker.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"
14
15GoogleURLTrackerNavigationHelperImpl::GoogleURLTrackerNavigationHelperImpl(
16    content::WebContents* web_contents,
17    GoogleURLTracker* tracker)
18    : GoogleURLTrackerNavigationHelper(tracker),
19      web_contents_(web_contents) {
20}
21
22GoogleURLTrackerNavigationHelperImpl::~GoogleURLTrackerNavigationHelperImpl() {
23  web_contents_ = NULL;
24}
25
26void GoogleURLTrackerNavigationHelperImpl::SetListeningForNavigationCommit(
27    bool listen) {
28  content::NotificationSource navigation_controller_source =
29      content::Source<content::NavigationController>(
30          &web_contents_->GetController());
31  if (listen) {
32    registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
33                    navigation_controller_source);
34  } else {
35    registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
36                      navigation_controller_source);
37  }
38}
39
40bool GoogleURLTrackerNavigationHelperImpl::IsListeningForNavigationCommit() {
41  content::NotificationSource navigation_controller_source =
42      content::Source<content::NavigationController>(
43          &web_contents_->GetController());
44  return registrar_.IsRegistered(
45      this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
46      navigation_controller_source);
47}
48
49void GoogleURLTrackerNavigationHelperImpl::SetListeningForTabDestruction(
50    bool listen) {
51  content::NotificationSource web_contents_source =
52      content::Source<content::WebContents>(web_contents_);
53  if (listen) {
54    registrar_.Add(this,
55                   content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
56                   web_contents_source);
57  } else {
58    registrar_.Remove(this,
59                      content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
60                      web_contents_source);
61  }
62}
63
64bool GoogleURLTrackerNavigationHelperImpl::IsListeningForTabDestruction() {
65  return registrar_.IsRegistered(
66      this,
67      content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
68      content::Source<content::WebContents>(web_contents_));
69}
70
71void GoogleURLTrackerNavigationHelperImpl::OpenURL(
72    GURL url,
73    WindowOpenDisposition disposition,
74    bool user_clicked_on_link) {
75  ui::PageTransition transition_type = user_clicked_on_link ?
76      ui::PAGE_TRANSITION_LINK : ui::PAGE_TRANSITION_GENERATED;
77  web_contents_->OpenURL(content::OpenURLParams(
78      url, content::Referrer(), disposition, transition_type, false));
79}
80
81void GoogleURLTrackerNavigationHelperImpl::Observe(
82    int type,
83    const content::NotificationSource& source,
84    const content::NotificationDetails& details) {
85  switch (type) {
86    case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
87      content::NavigationController* controller =
88          content::Source<content::NavigationController>(source).ptr();
89      DCHECK_EQ(web_contents_, controller->GetWebContents());
90
91      // Here we're only listening to notifications where we already know
92      // there's an associated InfoBarService.
93      InfoBarService* infobar_service =
94          InfoBarService::FromWebContents(web_contents_);
95      DCHECK(infobar_service);
96      const GURL& search_url = controller->GetActiveEntry()->GetURL();
97      if (!search_url.is_valid())  // Not clear if this can happen.
98        google_url_tracker()->OnTabClosed(this);
99      google_url_tracker()->OnNavigationCommitted(infobar_service, search_url);
100      break;
101    }
102
103    case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: {
104      DCHECK_EQ(web_contents_,
105                content::Source<content::WebContents>(source).ptr());
106      google_url_tracker()->OnTabClosed(this);
107      break;
108    }
109
110    default:
111      NOTREACHED() << "Unknown notification received:" << type;
112  }
113}
114