1 // Copyright 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 #ifndef CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_NAVIGATION_OBSERVER_H_ 6 #define CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_NAVIGATION_OBSERVER_H_ 7 8 #include <string> 9 10 #include "base/memory/ref_counted.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "chrome/browser/autocomplete/autocomplete_match.h" 13 #include "content/public/browser/notification_observer.h" 14 #include "content/public/browser/notification_registrar.h" 15 #include "content/public/browser/web_contents_observer.h" 16 #include "net/url_request/url_fetcher_delegate.h" 17 18 class ShortcutsBackend; 19 20 namespace net { 21 class URLFetcher; 22 class URLRequestStatus; 23 } 24 25 // Monitors omnibox navigations in order to trigger behaviors that depend on 26 // successful navigations. 27 // 28 // Currently two such behaviors exist: 29 // (1) For single-word queries where we can't tell if the entry was a search or 30 // an intranet hostname, the omnibox opens as a search by default, but this 31 // class attempts to open as a URL via an HTTP HEAD request. If successful, 32 // displays an infobar once the search result has also loaded. See 33 // AlternateNavInfoBarDelegate. 34 // (2) Omnibox navigations that complete successfully are added to the 35 // Shortcuts backend. 36 // 37 // TODO(pkasting): Probably NOTIFICATION_OMNIBOX_OPENED_URL should disappear and 38 // everyone who listened to it should be triggered from this class instead. 39 // 40 // The memory management of this object is a bit tricky. The OmniboxEditModel 41 // will create us and be responsible for us until we attach as an observer 42 // after a pending load starts (it will delete us if this doesn't happen). 43 // Once this pending load starts, we're responsible for deleting ourselves. 44 class OmniboxNavigationObserver : public content::NotificationObserver, 45 public content::WebContentsObserver, 46 public net::URLFetcherDelegate { 47 public: 48 enum LoadState { 49 LOAD_NOT_SEEN, 50 LOAD_PENDING, 51 LOAD_COMMITTED, 52 }; 53 54 OmniboxNavigationObserver(Profile* profile, 55 const base::string16& text, 56 const AutocompleteMatch& match, 57 const AutocompleteMatch& alternate_nav_match); 58 virtual ~OmniboxNavigationObserver(); 59 60 LoadState load_state() const { return load_state_; } 61 62 // Called directly by OmniboxEditModel when an extension-related navigation 63 // occurs. Such navigations don't trigger an immediate NAV_ENTRY_PENDING and 64 // must be handled separately. 65 void OnSuccessfulNavigation(); 66 67 private: 68 enum FetchState { 69 FETCH_NOT_COMPLETE, 70 FETCH_SUCCEEDED, 71 FETCH_FAILED, 72 }; 73 74 // content::NotificationObserver: 75 virtual void Observe(int type, 76 const content::NotificationSource& source, 77 const content::NotificationDetails& details) OVERRIDE; 78 79 // content::WebContentsObserver: 80 virtual void DidStartNavigationToPendingEntry( 81 const GURL& url, 82 content::NavigationController::ReloadType reload_type) OVERRIDE; 83 virtual void NavigationEntryCommitted( 84 const content::LoadCommittedDetails& load_details) OVERRIDE; 85 virtual void WebContentsDestroyed() OVERRIDE; 86 87 // net::URLFetcherDelegate: 88 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 89 90 // Once the load has committed and any URL fetch has completed, this displays 91 // the alternate nav infobar if necessary, and deletes |this|. 92 void OnAllLoadingFinished(); 93 94 const base::string16 text_; 95 const AutocompleteMatch match_; 96 const AutocompleteMatch alternate_nav_match_; 97 scoped_refptr<ShortcutsBackend> shortcuts_backend_; // NULL in incognito. 98 scoped_ptr<net::URLFetcher> fetcher_; 99 LoadState load_state_; 100 FetchState fetch_state_; 101 102 content::NotificationRegistrar registrar_; 103 104 DISALLOW_COPY_AND_ASSIGN(OmniboxNavigationObserver); 105 }; 106 107 #endif // CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_NAVIGATION_OBSERVER_H_ 108