1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_PREDICTORS_AUTOCOMPLETE_ACTION_PREDICTOR_H_
#define CHROME_BROWSER_PREDICTORS_AUTOCOMPLETE_ACTION_PREDICTOR_H_
#include <map>
#include <memory>
#include <set>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/scoped_observation.h"
#include "chrome/browser/predictors/autocomplete_action_predictor_table.h"
#include "components/history/core/browser/history_service.h"
#include "components/history/core/browser/history_service_observer.h"
#include "components/history/core/browser/history_types.h"
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/web_contents.h"
#include "url/gurl.h"
struct AutocompleteMatch;
class AutocompleteResult;
struct OmniboxLog;
class PredictorsHandler;
class Profile;
namespace gfx {
class Size;
}
namespace history {
class URLDatabase;
}
namespace predictors {
// This class is responsible for determining the correct predictive network
// action to take given for a given AutocompleteMatch and entered text. It can
// be instantiated for both normal and incognito profiles. For normal profiles,
// it uses an AutocompleteActionPredictorTable accessed asynchronously on the DB
// thread to permanently store the data used to make predictions, and keeps
// local caches of that data to be able to make predictions synchronously on the
// UI thread where it lives. For incognito profiles, there is no table; the
// local caches are copied from the main profile at creation and from there on
// are the only thing used.
//
// This class can be accessed as a weak pointer so that it can safely use
// PostTaskAndReply without fear of crashes if it is destroyed before the reply
// triggers. This is necessary during initialization.
class AutocompleteActionPredictor : public KeyedService,
public history::HistoryServiceObserver {
public:
struct TransitionalMatch {
TransitionalMatch();
explicit TransitionalMatch(const std::u16string in_user_text);
TransitionalMatch(const TransitionalMatch& other);
~TransitionalMatch();
std::u16string user_text;
std::vector<GURL> urls;
};
// An `Action` is a recommendation on what pre* technology to invoke on a
// given `AutocompleteMatch`.
enum Action {
// Trigger Prerendering.
ACTION_PRERENDER = 0,
// Invoke `LoadingPredictor::PrepareForPageLoad` to
// prefetch, preconnect, and preresolve.
ACTION_PRECONNECT,
// The recommendation is to not perform any action.
ACTION_NONE,
};
explicit AutocompleteActionPredictor(Profile* profile);
AutocompleteActionPredictor(const AutocompleteActionPredictor&) = delete;
AutocompleteActionPredictor& operator=(const AutocompleteActionPredictor&) =
delete;
~AutocompleteActionPredictor() override;
class Observer : public base::CheckedObserver {
public:
// Called once per FinishInitialization() call.
virtual void OnInitialized() {}
};
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// Registers an AutocompleteResult for a given |user_text|. This will be used
// when the user navigates from the Omnibox to determine early opportunities
// to predict their actions.
void RegisterTransitionalMatches(const std::u16string& user_text,
const AutocompleteResult& result);
// Updates the database using the current transitional matches, given the URL
// the user navigated to (or an empty URL if the user did not navigate). This
// clears the transitional matches.
void UpdateDatabaseFromTransitionalMatches(const GURL& opened_url);
// Clears any transitional matches that have been registered. Called when, for
// example, the OmniboxEditModel is reverted.
void ClearTransitionalMatches();
// Returns the recommended action given |user_text|, the text the user has
// entered in the Omnibox associated with |web_contents|, and |match|, the
// suggestion from Autocomplete. This method uses information from the
// ShortcutsBackend including how much of the matching entry the user typed,
// and how long it's been since the user visited the matching URL, to
// calculate a score between 0 and 1. This score is then mapped to an Action.
Action RecommendAction(const std::u16string& user_text,
const AutocompleteMatch& match,
content::WebContents* web_contents) const;
// The predictor will run at most one prerender
// at a time, so launching a prerender will cancel our previous prerenders (if
// any).
void StartPrerendering(const GURL& url, content::WebContents& web_contents);
// Returns true if the suggestion type warrants a TCP/IP preconnection.
// i.e., it is now quite likely that the user will select the related domain.
static bool IsPreconnectable(const AutocompleteMatch& match);
// Should be called when a URL is opened from the omnibox.
void OnOmniboxOpenedUrl(const OmniboxLog& log);
// Uses local caches to calculate an exact percentage prediction that the user
// will take a particular match given what they have typed.
double CalculateConfidence(const std::u16string& user_text,
const AutocompleteMatch& match) const;
bool initialized() { return initialized_; }
static Action DecideActionByConfidence(double confidence);
private:
friend class AutocompleteActionPredictorTest;
friend class ::PredictorsHandler;
struct DBCacheKey {
std::u16string user_text;
GURL url;
bool operator<(const DBCacheKey& rhs) const {
return std::tie(user_text, url) < std::tie(rhs.user_text, rhs.url);
}
bool operator==(const DBCacheKey& rhs) const {
return (user_text == rhs.user_text) && (url == rhs.url);
}
};
struct DBCacheValue {
int number_of_hits;
int number_of_misses;
};
typedef std::map<DBCacheKey, DBCacheValue> DBCacheMap;
typedef std::map<DBCacheKey, AutocompleteActionPredictorTable::Row::Id>
DBIdCacheMap;
static const int kMaximumDaysToKeepEntry;
static const size_t kMinimumUserTextLength;
static const size_t kMaximumStringLength;
// Removes all rows from the database and caches.
void DeleteAllRows();
// Removes rows that contain a URL in |rows| from the local caches.
// |id_list| must not be nullptr. Every row id deleted will be added to
// |id_list|.
void DeleteRowsFromCaches(
const history::URLRows& rows,
std::vector<AutocompleteActionPredictorTable::Row::Id>* id_list);
// Adds and updates rows in the database and caches.
void AddAndUpdateRows(
const AutocompleteActionPredictorTable::Rows& rows_to_add,
const AutocompleteActionPredictorTable::Rows& rows_to_update);
// Called to populate the local caches. This also calls DeleteOldEntries
// if the history service is available, or registers for the notification of
// it becoming available.
void CreateCaches(
std::unique_ptr<std::vector<AutocompleteActionPredictorTable::Row>> rows);
// Attempts to call DeleteOldEntries if the in-memory database has been loaded
// by |service|.
void TryDeleteOldEntries(history::HistoryService* service);
// Called to delete any old or invalid entries from the database. Called after
// the local caches are created once the history service is available.
void DeleteOldEntries(history::URLDatabase* url_db);
// Deletes any old or invalid entries from the local caches. |url_db| and
// |id_list| must not be nullptr. Every row id deleted will be added to
// |id_list|.
void DeleteOldIdsFromCaches(
history::URLDatabase* url_db,
std::vector<AutocompleteActionPredictorTable::Row::Id>* id_list);
// Deletes up to |count| rows having lowest confidence scores from the local
// caches. Deleted row ids will be added to |id_list|.
void DeleteLowestConfidenceRowsFromCaches(
size_t count,
std::vector<AutocompleteActionPredictorTable::Row::Id>* id_list);
// Called on an incognito-owned predictor to copy the current caches from the
// main profile.
void CopyFromMainProfile();
// Registers for notifications and sets the |initialized_| flag.
void FinishInitialization();
// Calculates the confidence for an entry in the DBCacheMap.
double CalculateConfidenceForDbEntry(DBCacheMap::const_iterator iter) const;
// KeyedService:
void Shutdown() override;
// history::HistoryServiceObserver:
void OnHistoryDeletions(history::HistoryService* history_service,
const history::DeletionInfo& deletion_info) override;
void OnHistoryServiceLoaded(
history::HistoryService* history_service) override;
raw_ptr<Profile> profile_ = nullptr;
// Set when this is a predictor for an incognito profile.
raw_ptr<AutocompleteActionPredictor> main_profile_predictor_ = nullptr;
// Set when this is a predictor for a non-incognito profile, and the incognito
// profile creates a predictor. If this is non-NULL when we finish
// initialization, we should call CopyFromMainProfile() on it.
raw_ptr<AutocompleteActionPredictor> incognito_predictor_ = nullptr;
// The backing data store. This is nullptr for incognito-owned predictors.
scoped_refptr<AutocompleteActionPredictorTable> table_;
// This is cleared after every Omnibox navigation.
std::vector<TransitionalMatch> transitional_matches_;
// The aggregated size of all user text and GURLs in |transitional_matches_|.
// This is used to limit the maximum size of |transitional_matches_|.
size_t transitional_matches_size_ = 0;
base::WeakPtr<content::PrerenderHandle> direct_url_input_prerender_handle_;
// Local caches of the data store. For incognito-owned predictors this is the
// only copy of the data.
DBCacheMap db_cache_;
DBIdCacheMap db_id_cache_;
bool initialized_ = false;
base::ObserverList<Observer> observers_;
base::ScopedObservation<history::HistoryService,
history::HistoryServiceObserver>
history_service_observation_{this};
base::WeakPtrFactory<AutocompleteActionPredictor> weak_ptr_factory_{this};
};
} // namespace predictors
#endif // CHROME_BROWSER_PREDICTORS_AUTOCOMPLETE_ACTION_PREDICTOR_H_
|