Home | History | Annotate | Download | only in google
      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/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"
     14 
     15 GoogleURLTrackerNavigationHelperImpl::
     16     GoogleURLTrackerNavigationHelperImpl() : tracker_(NULL) {
     17 }
     18 
     19 GoogleURLTrackerNavigationHelperImpl::
     20     ~GoogleURLTrackerNavigationHelperImpl() {
     21 }
     22 
     23 void GoogleURLTrackerNavigationHelperImpl::SetGoogleURLTracker(
     24     GoogleURLTracker* tracker) {
     25   DCHECK(tracker);
     26   tracker_ = tracker;
     27 }
     28 
     29 void GoogleURLTrackerNavigationHelperImpl::SetListeningForNavigationStart(
     30     bool listen) {
     31   if (listen) {
     32     registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
     33         content::NotificationService::AllBrowserContextsAndSources());
     34   } else {
     35     registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
     36         content::NotificationService::AllBrowserContextsAndSources());
     37   }
     38 }
     39 
     40 bool GoogleURLTrackerNavigationHelperImpl::IsListeningForNavigationStart() {
     41   return registrar_.IsRegistered(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
     42       content::NotificationService::AllBrowserContextsAndSources());
     43 }
     44 
     45 void GoogleURLTrackerNavigationHelperImpl::SetListeningForNavigationCommit(
     46     const content::NavigationController* nav_controller,
     47     bool listen) {
     48   content::NotificationSource navigation_controller_source =
     49       content::Source<content::NavigationController>(nav_controller);
     50   if (listen) {
     51     registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
     52                     navigation_controller_source);
     53   } else {
     54     registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
     55                       navigation_controller_source);
     56   }
     57 }
     58 
     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);
     66 }
     67 
     68 void GoogleURLTrackerNavigationHelperImpl::SetListeningForTabDestruction(
     69     const content::NavigationController* nav_controller,
     70     bool listen) {
     71   content::NotificationSource navigation_controller_source =
     72       content::Source<content::NavigationController>(nav_controller);
     73   if (listen) {
     74     registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
     75                    GetWebContentsSource(navigation_controller_source));
     76   } else {
     77     registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
     78                       GetWebContentsSource(navigation_controller_source));
     79   }
     80 }
     81 
     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(
     87       this,
     88       content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
     89       GetWebContentsSource(navigation_controller_source));
     90 }
     91 
     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);
    100 }
    101 
    102 void GoogleURLTrackerNavigationHelperImpl::Observe(
    103     int type,
    104     const content::NotificationSource& source,
    105     const content::NotificationDetails& details) {
    106   switch (type) {
    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());
    120       }
    121       break;
    122     }
    123 
    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);
    137       break;
    138     }
    139 
    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());
    144       break;
    145     }
    146 
    147     default:
    148       NOTREACHED() << "Unknown notification received:" << type;
    149   }
    150 }
    151