blob: d0e2042a702f26971123e298108b3a7cdc67138f [file] [log] [blame]
// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_OMNIBOX_CHROME_OMNIBOX_NAVIGATION_OBSERVER_H_
#define CHROME_BROWSER_UI_OMNIBOX_CHROME_OMNIBOX_NAVIGATION_OBSERVER_H_
#include <memory>
#include <string>
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/omnibox_navigation_observer.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/reload_type.h"
#include "content/public/browser/web_contents_observer.h"
#include "net/url_request/url_fetcher_delegate.h"
class Profile;
class ShortcutsBackend;
class TemplateURLService;
namespace network {
class SharedURLLoaderFactory;
class SimpleURLLoader;
}
// Monitors omnibox navigations in order to trigger behaviors that depend on
// successful navigations.
//
// Currently three such behaviors exist:
// (1) For single-word queries where we can't tell if the entry was a search or
// an intranet hostname, the omnibox opens as a search by default, but this
// class attempts to open as a URL via an HTTP HEAD request. If successful,
// displays an infobar once the search result has also loaded. See
// AlternateNavInfoBarDelegate.
// (2) Omnibox navigations that complete successfully are added to the
// Shortcuts backend.
// (3) Omnibox searches that result in a 404 for an auto-generated custom
// search engine cause the custom search engine to be deleted.
//
// Please see the class comment on the base class for important information
// about the memory management of this object.
class ChromeOmniboxNavigationObserver : public OmniboxNavigationObserver,
public content::NotificationObserver,
public content::WebContentsObserver {
public:
enum LoadState {
LOAD_NOT_SEEN,
LOAD_PENDING,
LOAD_COMMITTED,
};
ChromeOmniboxNavigationObserver(Profile* profile,
const base::string16& text,
const AutocompleteMatch& match,
const AutocompleteMatch& alternate_nav_match);
~ChromeOmniboxNavigationObserver() override;
LoadState load_state() const { return load_state_; }
// Called directly by ChromeOmniboxClient when an extension-related navigation
// occurs. Such navigations don't trigger an immediate NAV_ENTRY_PENDING and
// must be handled separately.
void OnSuccessfulNavigation();
// Called when a navigation that yields a 404 ("Not Found") occurs. If this
// navigation was an omnibox search that invoked an auto-generated custom
// search engine, delete the engine. This will prevent the user from using
// the broken engine again.
void On404();
// Test-only method to override how loading happens. Normally this is
// extracted from the profile passed to the constructor.
void SetURLLoaderFactoryForTesting(
scoped_refptr<network::SharedURLLoaderFactory> testing_loader_factory);
protected:
// Creates/displays the alternate nav infobar. Overridden in tests.
virtual void CreateAlternateNavInfoBar();
private:
FRIEND_TEST_ALL_PREFIXES(ChromeOmniboxNavigationObserverTest,
DeleteBrokenCustomSearchEngines);
FRIEND_TEST_ALL_PREFIXES(ChromeOmniboxNavigationObserverTest,
AlternateNavInfoBar);
enum FetchState {
FETCH_NOT_COMPLETE,
FETCH_SUCCEEDED,
FETCH_FAILED,
};
// OmniboxNavigationObserver:
bool HasSeenPendingLoad() const override;
// content::NotificationObserver:
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
// content::WebContentsObserver:
void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override;
void NavigationEntryCommitted(
const content::LoadCommittedDetails& load_details) override;
void WebContentsDestroyed() override;
// Used as callbacks from |loader_|.
void OnURLLoadComplete(std::unique_ptr<std::string> body);
// See SimpleURLLoader::OnRedirectCallback for info on the signature.
void OnURLRedirect(const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head,
std::vector<std::string>* to_be_removed_headers);
// Called from either OnURLLoadComplete or OnURLRedirect.
void OnDoneWithURL(bool success);
// Once the load has committed and any URL fetch has completed, this displays
// the alternate nav infobar if necessary, and deletes |this|.
void OnAllLoadingFinished();
// Creates a URL loader for |destination_url| and stores it in |loader_|.
// Does not start the loader.
void CreateLoader(const GURL& destination_url);
const base::string16 text_;
const AutocompleteMatch match_;
const AutocompleteMatch alternate_nav_match_;
TemplateURLService* template_url_service_;
scoped_refptr<ShortcutsBackend> shortcuts_backend_; // NULL in incognito.
std::unique_ptr<network::SimpleURLLoader> loader_;
scoped_refptr<network::SharedURLLoaderFactory> loader_factory_for_testing_;
LoadState load_state_;
FetchState fetch_state_;
content::NotificationRegistrar registrar_;
DISALLOW_COPY_AND_ASSIGN(ChromeOmniboxNavigationObserver);
};
#endif // CHROME_BROWSER_UI_OMNIBOX_CHROME_OMNIBOX_NAVIGATION_OBSERVER_H_