File: autocomplete_action_predictor.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (278 lines) | stat: -rw-r--r-- 10,551 bytes parent folder | download | duplicates (5)
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_