File: document_provider.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 (195 lines) | stat: -rw-r--r-- 8,490 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
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// This file contains the document autocomplete provider. This experimental
// provider uses an experimental API with keys and endpoint provided at
// developer build-time, so it is feature-flagged off by default.

#ifndef COMPONENTS_OMNIBOX_BROWSER_DOCUMENT_PROVIDER_H_
#define COMPONENTS_OMNIBOX_BROWSER_DOCUMENT_PROVIDER_H_

#include <memory>
#include <string>

#include "base/compiler_specific.h"
#include "base/containers/lru_cache.h"
#include "base/feature_list.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "components/history/core/browser/history_types.h"
#include "components/omnibox/browser/autocomplete_enums.h"
#include "components/omnibox/browser/autocomplete_provider.h"
#include "components/omnibox/browser/autocomplete_provider_debouncer.h"
#include "third_party/metrics_proto/omnibox_event.pb.h"
#include "url/gurl.h"

class AutocompleteProviderListener;
struct AutocompleteMatch;
class AutocompleteProviderClient;

namespace base {
class Value;
}

namespace network {
class SimpleURLLoader;
}

// Autocomplete provider for personalized documents owned or readable by the
// signed-in user. In practice this is a second request in parallel with that
// to the default search provider.
class DocumentProvider : public AutocompleteProvider {
 public:
  // Creates and returns an instance of this provider.
  static DocumentProvider* Create(AutocompleteProviderClient* client,
                                  AutocompleteProviderListener* listener);

  // AutocompleteProvider:
  void Start(const AutocompleteInput& input, bool minimal_changes) override;
  void Stop(AutocompleteStopReason stop_reason) override;
  void DeleteMatch(const AutocompleteMatch& match) override;
  void AddProviderInfo(ProvidersInfo* provider_info) const override;

  // Returns a set of classifications that highlight all the occurrences of
  // |input_text| at word breaks in |text|. E.g., given |input_text|
  // "rain if you dare" and |text| "how to tell if your kitten is a rainbow",
  // will return the classifications:
  //             __ ___              ____
  // how to tell if your kitten is a rainbow
  // ^           ^ ^^   ^            ^  ^
  // NONE        M |M   |            |  NONE
  //               NONE NONE         MATCH
  static ACMatchClassifications Classify(const std::u16string& input_text,
                                         const std::u16string& text);

  // Builds a GURL to use for deduping against other document/history
  // suggestions. Multiple URLs may refer to the same document.
  // Returns an empty GURL if not a recognized Docs URL.
  // The URL returned is not guaranteed to be navigable and should only be used
  // as a deduping token.
  static const GURL GetURLForDeduping(const GURL& url);

 private:
  friend class FakeDocumentProvider;

  using MatchesCache = base::LRUCache<GURL, AutocompleteMatch>;

  DocumentProvider(AutocompleteProviderClient* client,
                   AutocompleteProviderListener* listener);

  ~DocumentProvider() override;

  DocumentProvider(const DocumentProvider&) = delete;
  DocumentProvider& operator=(const DocumentProvider&) = delete;

  // Determines whether the profile/session/window meet the feature
  // prerequisites.
  bool IsDocumentProviderAllowed(const AutocompleteInput& input);

  // Determines if the input is a URL, or is the start of the user entering one.
  // We avoid queries for these cases for quality and scaling reasons.
  static bool IsInputLikelyURL(const AutocompleteInput& input);

  // Called by |debouncer_|, queued when |start| is called.
  void Run(const AutocompleteInput& input);

  // Called when the network request for suggestions has completed.
  void OnURLLoadComplete(const network::SimpleURLLoader* source,
                         const int response_code,
                         std::unique_ptr<std::string> response_body);

  // Resets the backoff state on DocumentSuggestionsService to false.
  void ResetBackoffState();

  // The function updates |matches_| with data parsed from |json_data|.
  // The update is not performed if |json_data| is invalid.
  // Returns whether |matches_| changed.
  bool UpdateResults(const std::string& json_data);

  // Callback for when the loader is available with a valid token.
  void OnDocumentSuggestionsLoaderAvailable(
      std::unique_ptr<network::SimpleURLLoader> loader);

  // Parses document search result JSON.
  // Returns true if |matches| was populated with fresh suggestions.
  ACMatches ParseDocumentSearchResults(const base::Value& root_val);

  // Appends |matches_cache_| to |matches_|. Updates their classifications
  // according to |input_.text()|.
  void CopyCachedMatchesToMatches();

  // Sets the scores of all cached matches to 0. This is invoked before pushing
  // the latest async response returns so that the scores aren't preserved for
  // further inputs. E.g., the input 'london' shouldn't display cached docs from
  // a previous input 'paris'. This can't be done by automatically (i.e. set
  // scores to 0 before pushing to the cache), as the scores are needed for the
  // async pass if the user continued their input.
  void SetCachedMatchesScoresTo0();

  // Sets the scores of matches beyond the first |provider_max_matches_| to 0.
  // This ensures the doc provider doesn't exceed it's allocated suggestions
  // while also allowing docs from other providers to be deduped and styled like
  // docs from the doc provider.
  void DemoteMatchesBeyondMax();

  // Generates the localized last-modified timestamp to present to the user.
  // Full date for old files, mm/dd within the same calendar year, or time-of-
  // day if a file was modified on the same date.
  // |now| should generally be base::Time::Now() but is passed in for testing.
  static std::u16string GenerateLastModifiedString(
      const std::string& modified_timestamp_string,
      base::Time now);

  // Convert mimetype (e.g. "application/vnd.google-apps.document") to a string
  // that can be used in the match description (e.g. "Google Docs").
  static std::u16string GetProductDescriptionString(
      const std::string& mimetype);

  // Construct match description; e.g. "Jan 12 - First Last - Google Docs".
  static std::u16string GetMatchDescription(const std::string& update_time,
                                            const std::string& mimetype,
                                            const std::string& owner);

  // Whether the server has instructed us to backoff. Used when the backoff
  // state is scoped to the current window/AutocompleteController.
  bool backoff_for_this_instance_only_ = false;

  // Client for accessing TemplateUrlService, prefs, etc.
  raw_ptr<AutocompleteProviderClient> client_;

  // Saved when starting a new autocomplete request so that it can be retrieved
  // when responses return asynchronously.
  AutocompleteInput input_;

  // Loader used to retrieve results.
  std::unique_ptr<network::SimpleURLLoader> loader_;

  // The time `Run()` was invoked. Used for histogram logging.
  base::TimeTicks time_run_invoked_;
  // The time `OnDocumentSuggestionsLoaderAvailable()` was invoked and the
  // remote request was sent. Used for histogram logging.
  base::TimeTicks time_request_sent_;

  // Used to ensure that we don't send multiple requests in quick succession.
  std::unique_ptr<AutocompleteProviderDebouncer> debouncer_;

  // Because the drive server is async and may intermittently provide a
  // particular suggestion for consecutive inputs, without caching, doc
  // suggestions flicker between drive format (title - date - doc_type) and URL
  // format (title - URL) suggestions from the history and bookmark providers.
  // Appending cached doc suggestions with relevance 0 ensures cached
  // suggestions only display if deduped with a non-cached suggestion and do not
  // affect which autocomplete results are displayed and their ranks.
  MatchesCache matches_cache_;

  // Used to schedule a reset of the backoff state.
  scoped_refptr<base::SequencedTaskRunner> task_runner_;

  // For callbacks that may be run after destruction. Must be declared last.
  base::WeakPtrFactory<DocumentProvider> weak_ptr_factory_{this};
};

#endif  // COMPONENTS_OMNIBOX_BROWSER_DOCUMENT_PROVIDER_H_