blob: 2615d9413cd5996f541a51878084519131916d74 [file] [log] [blame]
// Copyright (c) 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.
//
// This file contains the zero-suggest autocomplete provider. This experimental
// provider is invoked when the user focuses in the omnibox prior to editing,
// and generates search query suggestions based on the current URL.
#ifndef COMPONENTS_OMNIBOX_BROWSER_ZERO_SUGGEST_PROVIDER_H_
#define COMPONENTS_OMNIBOX_BROWSER_ZERO_SUGGEST_PROVIDER_H_
#include <memory>
#include <string>
#include "base/gtest_prod_util.h"
#include "components/omnibox/browser/base_search_provider.h"
#include "components/omnibox/browser/search_provider.h"
#include "third_party/metrics_proto/omnibox_event.pb.h"
class AutocompleteProviderListener;
class PrefRegistrySimple;
namespace network {
class SimpleURLLoader;
}
// Autocomplete provider for searches based on the current URL.
//
// The controller will call Start() when the user focuses the omnibox. After
// construction, the autocomplete controller repeatedly calls Start() with some
// user input, each time expecting to receive an updated set of matches.
//
// TODO(jered): Consider deleting this class and building this functionality
// into SearchProvider after dogfood and after we break the association between
// omnibox text and suggestions.
class ZeroSuggestProvider : public BaseSearchProvider {
public:
// The result type that can be processed by ZeroSuggestProvider.
// Public for testing purposes and for use in LocalHistoryZeroSuggestProvider.
enum class ResultType {
kNone = 0,
// The remote endpoint is queried for zero-prefix suggestions. The endpoint
// is sent the user's authentication state, but not the current papge URL.
kRemoteNoURL = 1,
// The emote endpoint is queried for zero-prefix suggestions. The endpoint
// is sent both the user's authentication state and the current page URL.
kRemoteSendURL = 2,
};
// Returns the type of results that should be generated for the given context;
// however, it does not check whether or not a suggest request can be made.
// Those checks must be done using BaseSearchProvider::CanSendRequest() and
// BaseSearchProvider::CanSendPageURLInRequest() for the kRemoteNoURL and
// kRemoteSendURL variants respectively.
// This method is static to avoid depending on the provider state.
static ResultType ResultTypeToRun(const AutocompleteProviderClient* client,
const AutocompleteInput& input);
// Called in Start() or StartPrefetch(), confirms whether zero-prefix
// suggestions are allowed in the given context and logs eligibility UMA
// metrics. Must be called exactly once. Otherwise the meaning of the the
// metrics it logs would change.
// This method is static to avoid depending on the provider state.
static bool AllowZeroPrefixSuggestions(
const AutocompleteProviderClient* client,
const AutocompleteInput& input);
// Creates and returns an instance of this provider.
static ZeroSuggestProvider* Create(AutocompleteProviderClient* client,
AutocompleteProviderListener* listener);
// Registers a preference used to cache the zero suggest response.
static void RegisterProfilePrefs(PrefRegistrySimple* registry);
// AutocompleteProvider:
void StartPrefetch(const AutocompleteInput& input) override;
void Start(const AutocompleteInput& input, bool minimal_changes) override;
void Stop(bool clear_cached_results,
bool due_to_user_inactivity) override;
void DeleteMatch(const AutocompleteMatch& match) override;
void AddProviderInfo(ProvidersInfo* provider_info) const override;
// Sets |field_trial_triggered_| to false.
void ResetSession() override;
// Returns the list of experiment stats corresponding to |matches_|. Will be
// logged to SearchboxStats as part of a GWS experiment, if any.
const SearchSuggestionParser::ExperimentStatsV2s& experiment_stats_v2s()
const {
return experiment_stats_v2s_;
}
ResultType GetResultTypeRunningForTesting() const {
return result_type_running_;
}
private:
ZeroSuggestProvider(AutocompleteProviderClient* client,
AutocompleteProviderListener* listener);
~ZeroSuggestProvider() override;
ZeroSuggestProvider(const ZeroSuggestProvider&) = delete;
ZeroSuggestProvider& operator=(const ZeroSuggestProvider&) = delete;
// BaseSearchProvider:
bool ShouldAppendExtraParams(
const SearchSuggestionParser::SuggestResult& result) const override;
void RecordDeletionResult(bool success) override;
// Called when the non-prefetch network request has completed.
// `input` and `result_type` are bound to this callback. The former is the
// input for which the request was made and the latter indicates the result
// type being received in this callback.
void OnURLLoadComplete(const AutocompleteInput& input,
ResultType result_type,
const network::SimpleURLLoader* source,
std::unique_ptr<std::string> response_body);
// Called when the prefetch network request has completed.
// `input` and `result_type` are bound to this callback. The former is the
// input for which the request was made and the latter indicates the result
// type being received in this callback.
void OnPrefetchURLLoadComplete(const AutocompleteInput& input,
ResultType result_type,
const network::SimpleURLLoader* source,
std::unique_ptr<std::string> response_body);
// Returns an AutocompleteMatch for a navigational suggestion |navigation|.
AutocompleteMatch NavigationToMatch(
const SearchSuggestionParser::NavigationResult& navigation);
// Called either in Start() with |results| populated from the cached response,
// where |matches_| are empty; or in OnURLLoadComplete() with |results|
// populated from the remote response, where |matches_| may not be empty.
//
// Uses |results| and |input| to populate |matches_| and its associated
// metadata. Also logs how many results were received. Note that an empty
// result set will clear |matches_|.
void ConvertSuggestResultsToAutocompleteMatches(
const SearchSuggestionParser::Results& results,
const AutocompleteInput& input);
// The result type that is currently being retrieved and processed for
// non-prefetch requests.
// Set in Start() and used in Stop() for logging purposes.
ResultType result_type_running_{ResultType::kNone};
// Loader used to retrieve results for non-prefetch requests.
std::unique_ptr<network::SimpleURLLoader> loader_;
// Loader used to retrieve results for prefetch requests.
std::unique_ptr<network::SimpleURLLoader> prefetch_loader_;
// The list of experiment stats corresponding to |matches_|.
SearchSuggestionParser::ExperimentStatsV2s experiment_stats_v2s_;
// For callbacks that may be run after destruction.
base::WeakPtrFactory<ZeroSuggestProvider> weak_ptr_factory_{this};
};
#endif // COMPONENTS_OMNIBOX_BROWSER_ZERO_SUGGEST_PROVIDER_H_