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_ALTERNATE_NAV_URL_FETCHER_H_ 6 #define CHROME_BROWSER_UI_OMNIBOX_ALTERNATE_NAV_URL_FETCHER_H_ 7 8 #include <string> 9 10 #include "base/memory/scoped_ptr.h" 11 #include "content/public/browser/notification_observer.h" 12 #include "content/public/browser/notification_registrar.h" 13 #include "net/url_request/url_fetcher_delegate.h" 14 #include "url/gurl.h" 15 16 namespace content { 17 class NavigationController; 18 } 19 20 namespace net { 21 class URLFetcher; 22 class URLRequestStatus; 23 } 24 25 // Attempts to get the HEAD of a host name and displays an info bar if the 26 // request was successful. This is used for single-word queries where we can't 27 // tell if the entry was a search or an intranet hostname. The autocomplete bar 28 // assumes it's a query and issues an AlternateNavURLFetcher to display a "did 29 // you mean" infobar suggesting a navigation. 30 // 31 // The memory management of this object is a bit tricky. The location bar view 32 // will create us and be responsible for us until we attach as an observer 33 // after a pending load starts (it will delete us if this doesn't happen). 34 // Once this pending load starts, we're responsible for deleting ourselves. 35 // We'll do this in the following cases: 36 // * The tab is navigated again once we start listening (so the fetch is no 37 // longer useful) 38 // * The tab is closed before we show an infobar 39 // * The intranet fetch fails 40 // * None of the above apply, so we successfully show an infobar 41 class AlternateNavURLFetcher : public content::NotificationObserver, 42 public net::URLFetcherDelegate { 43 public: 44 enum State { 45 NOT_STARTED, 46 IN_PROGRESS, 47 SUCCEEDED, 48 FAILED, 49 }; 50 51 explicit AlternateNavURLFetcher(const GURL& alternate_nav_url); 52 virtual ~AlternateNavURLFetcher(); 53 54 State state() const { return state_; } 55 56 private: 57 // content::NotificationObserver 58 virtual void Observe(int type, 59 const content::NotificationSource& source, 60 const content::NotificationDetails& details) OVERRIDE; 61 62 // net::URLFetcherDelegate 63 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 64 65 // Sets |controller_| to the supplied pointer and begins fetching 66 // |alternate_nav_url_|. 67 void StartFetch(content::NavigationController* controller); 68 69 // Sets |state_| to either SUCCEEDED or FAILED depending on the result of the 70 // fetch. 71 void SetStatusFromURLFetch(const GURL& url, 72 const net::URLRequestStatus& status, 73 int response_code); 74 75 // Displays the infobar if all conditions are met (the page has loaded and 76 // the fetch of the alternate URL succeeded). Unless we're still waiting on 77 // one of the above conditions to finish, this will also delete us, as whether 78 // or not we show an infobar, there is no reason to live further. 79 void ShowInfobarIfPossible(); 80 81 GURL alternate_nav_url_; 82 scoped_ptr<net::URLFetcher> fetcher_; 83 content::NavigationController* controller_; 84 State state_; 85 bool navigated_to_entry_; 86 87 content::NotificationRegistrar registrar_; 88 89 DISALLOW_COPY_AND_ASSIGN(AlternateNavURLFetcher); 90 }; 91 92 #endif // CHROME_BROWSER_UI_OMNIBOX_ALTERNATE_NAV_URL_FETCHER_H_ 93