File: translate_manager.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 (376 lines) | stat: -rw-r--r-- 16,187 bytes parent folder | download | duplicates (6)
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
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_TRANSLATE_CORE_BROWSER_TRANSLATE_MANAGER_H_
#define COMPONENTS_TRANSLATE_CORE_BROWSER_TRANSLATE_MANAGER_H_

#include <map>
#include <memory>
#include <set>
#include <string>

#include "base/callback_list.h"
#include "base/feature_list.h"
#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "components/language_detection/core/constants.h"
#include "components/translate/core/browser/language_state.h"
#include "components/translate/core/browser/translate_metrics_logger.h"
#include "components/translate/core/common/translate_errors.h"

namespace language {
class LanguageModel;
}  // namespace language

namespace metrics {
class TranslateEventProto;
}  // namespace metrics

namespace translate {

class TranslateClient;
class TranslateDriver;
class TranslatePrefs;
class TranslateRanker;
struct TranslateTriggerDecision;

class NullTranslateMetricsLogger;

namespace testing {
class TranslateManagerTest;
}  // namespace testing

struct LanguageDetectionDetails;
struct TranslateErrorDetails;
struct TranslateInitDetails;

// The TranslateManager class is responsible for showing an info-bar when a page
// in a language different than the user language is loaded.  It triggers the
// page translation the user requests.

class TranslateManager {
 public:
  // |translate_client| is expected to outlive the TranslateManager.
  TranslateManager(TranslateClient* translate_client,
                   TranslateRanker* translate_ranker,
                   language::LanguageModel* language_model);

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

  virtual ~TranslateManager();

  // Returns a weak pointer to this instance.
  base::WeakPtr<TranslateManager> GetWeakPtr();

  // Cannot return NULL.
  TranslateClient* translate_client() { return translate_client_; }

  // Sets the sequence number of the current page, for use while sending
  // messages to the renderer.
  void set_current_seq_no(int page_seq_no) { page_seq_no_ = page_seq_no; }

  metrics::TranslateEventProto* mutable_translate_event() {
    return translate_event_.get();
  }

  // Returns the target language to show in the UI representing the current
  // page state.
  //
  // On a translated page it will be the language that a page is translated to.
  // On a non translated page it will be the result of |GetTargetlanguage|.
  std::string GetTargetLanguageForDisplay(
      TranslatePrefs* prefs,
      language::LanguageModel* language_model);

  // Returns the language to translate to.
  //
  // If provided a non-undefined |source_language|, returns the language from
  // the auto translate list (if not empty and it supports translate).
  //
  // If the recent target language is not empty and supports translate returns
  // that.
  //
  // If provided a non-null |language_model|, returns the first language from
  // the model that is supported by the translation service and that is not to
  // be skipped due to any ongoing experiment (see
  // |GetSkippedLanguagesForExperiments|).
  //
  // Otherwise, return the first language on the accept-language list that is
  // supported by the translation service
  //
  // If no language is found then "en" is returned.
  static std::string GetTargetLanguage(
      TranslatePrefs* prefs,
      language::LanguageModel* language_model,
      const std::string source_lang_code =
          language_detection::kUnknownLanguageCode);

  // Returns the language to automatically translate to. |source_language| is
  // the webpage's source language.
  static std::string GetAutoTargetLanguage(const std::string& source_language,
                                           TranslatePrefs* translate_prefs);

  // Translates the page contents from |source_lang| to |target_lang|.
  // The actual translation might be performed asynchronously if the translate
  // script is not yet available.
  void TranslatePage(
      const std::string& source_lang,
      const std::string& target_lang,
      bool triggered_from_menu,
      TranslationType translate_type = TranslationType::kUninitialized);

  // Starts the translation process for the page in the |page_lang| language.
  void InitiateTranslation(const std::string& page_lang);

  // Show the translation UI with the target language enforced to |target_lang|.
  // If |auto_translate| is true the page gets translated to the target
  // language.
  void ShowTranslateUI(const std::string& target_lang,
                       bool auto_translate = false,
                       bool triggered_from_menu = false);

  // Show the translation UI. If |auto_translate| is true the page gets
  // translated to the target language.
  void ShowTranslateUI(bool auto_translate = false,
                       bool triggered_from_menu = false);

  // Returns true iff the current page could be manually translated.
  // Logging should only be performed when this method is called to show the
  // Full Page Translate menu item.
  bool CanManuallyTranslate(bool menuLogging = false);

  // Whether or not partial translation is supported for the current target
  // language. Partial translate supports a subset of translation languages,
  // but shares a target language with full page translation.
  bool CanPartiallyTranslateTargetLanguage();

  bool IsMimeTypeSupported(const std::string& mime_type);

  // Shows the after translate or error infobar depending on the details.
  void PageTranslated(const std::string& source_lang,
                      const std::string& target_lang,
                      TranslateErrors error_type);

  // Reverts the contents of the page to its original language.
  void RevertTranslation();

  // Global Callbacks

  // The three callbacks below (translate error, translate initialization, and
  // language detected) are global for all WebContentses and should only be used
  // by translate-internals. All other clients should (probably) care about
  // which WebContents is being translated and therefore should instead use
  // LanguageDetectionObserver.

  // Callback types for translate errors.
  using TranslateErrorCallbackList =
      base::RepeatingCallbackList<void(const TranslateErrorDetails&)>;
  using TranslateErrorCallback = TranslateErrorCallbackList::CallbackType;

  // Callback types for translate initialization.
  using TranslateInitCallbackList =
      base::RepeatingCallbackList<void(const TranslateInitDetails&)>;
  using TranslateInitCallback = TranslateInitCallbackList::CallbackType;

  // Callback types for language detection.
  using LanguageDetectedCallbackList =
      base::RepeatingCallbackList<void(const LanguageDetectionDetails&)>;
  using LanguageDetectedCallback = LanguageDetectedCallbackList::CallbackType;

  // Registers a callback for translate errors.
  static base::CallbackListSubscription RegisterTranslateErrorCallback(
      const TranslateErrorCallback& callback);

  // Registers a callback for translate initialization.
  static base::CallbackListSubscription RegisterTranslateInitCallback(
      const TranslateInitCallback& callback);

  // Registers a callback for language detection.
  static base::CallbackListSubscription RegisterLanguageDetectedCallback(
      const LanguageDetectedCallback& callback);

  // Gets the LanguageState associated with the TranslateManager
  LanguageState* GetLanguageState();

  // Record an event of the given |event_type| using the currently saved
  // |translate_event_| as context. |event_type| must be one of the values
  // defined by metrics::TranslateEventProto::EventType.
  void RecordTranslateEvent(int event_type);

  // By default, don't offer to translate in builds lacking an API key. For
  // testing, set to true to offer anyway.
  static void SetIgnoreMissingKeyForTesting(bool ignore);

  // Returns true if the TranslateManager is available and enabled by user
  // preferences. It is not available for builds without API keys.
  // blink's hrefTranslate attribute existence relies on the result.
  // See https://github.com/dtapuska/html-translate
  static bool IsAvailable(const TranslatePrefs* prefs);

  // Returns true if the MATCHES_PREVIOUS_LANGUAGE decision should be overridden
  // and logs the event appropriately.
  bool ShouldOverrideMatchesPreviousLanguageDecision();

  // Returns true if the BubbleUI should be suppressed, where |target_language|
  // is the target language that would be shown in the UI.
  bool ShouldSuppressBubbleUI(const std::string& target_language);

  // Sets target language. Note that showing of the translate UI might still not
  // happen in certain situations, e.g. if the translation is prevented by user
  // prefs (i.e., blocklists), if |language_code| isn't a valid target language,
  // if the translate service isn't reachable, etc. Setting
  // |should_auto_translate| to true specifies both (1) that translation should
  // be initiated automatically and (2) that translation should occur even when
  // it would otherwise be prevented by user prefs.
  void SetPredefinedTargetLanguage(const std::string& language_code,
                                   bool should_auto_translate = false);

  // Returns a reference to |active_translate_metrics_logger_|. In the event
  // that this value is null, a |NullTranslateMetricsLogger| (a null
  // implementation) will be returned. This guarantees that the returned value
  // is always non-null.
  TranslateMetricsLogger* GetActiveTranslateMetricsLogger();

  // Sets |active_translate_metrics_logger_| to the given
  // |translate_metrics_logger|.
  void RegisterTranslateMetricsLogger(
      base::WeakPtr<TranslateMetricsLogger> translate_metrics_logger);

  // Called when the language of a page has been detected.
  void NotifyLanguageDetected(const LanguageDetectionDetails& details);

 private:
  friend class translate::testing::TranslateManagerTest;

  // Sends a translation request to the TranslateDriver.
  void DoTranslatePage(const std::string& translate_script,
                       const std::string& source_lang,
                       const std::string& target_lang);

  // Notifies all registered callbacks of translate errors.
  void NotifyTranslateError(TranslateErrors error_type);

  // Notifies all registered callbacks of translate initialization.
  void NotifyTranslateInit(std::string page_language_code,
                           std::string target_lang,
                           TranslateTriggerDecision decision,
                           bool ui_shown);

  // Called when the Translate script has been fetched.
  // Initiates the translation.
  void OnTranslateScriptFetchComplete(const std::string& source_lang,
                                      const std::string& target_lang,
                                      bool success);

  // Helper function to initialize a translate event metric proto.
  void InitTranslateEvent(const std::string& src_lang,
                          const std::string& dst_lang,
                          const TranslatePrefs& translate_prefs);

  void AddTargetLanguageToAcceptLanguages(
      const std::string& target_language_code);

  // Creates a TranslateTriggerDecision and filters out possible outcomes based
  // on the current state. Returns a decision objects ready to be used to
  // trigger behavior and record metrics.
  const TranslateTriggerDecision ComputePossibleOutcomes(
      TranslatePrefs* translate_prefs,
      const std::string& page_language_code,
      const std::string& target_lang);

  // Determines whether translation is even possible (connected to the internet,
  // source and target languages don't match, etc) and mutates |decision| based
  // on the result.
  void FilterIsTranslatePossible(TranslateTriggerDecision* decision,
                                 TranslatePrefs* translate_prefs,
                                 const std::string& page_language_code,
                                 const std::string& target_lang);

  // Determines whether auto-translate is a possible outcome, and mutates
  // |decision| accordingly.
  void FilterAutoTranslate(TranslateTriggerDecision* decision,
                           TranslatePrefs* translate_prefs,
                           const std::string& page_language_code);

  // Determines whether user prefs prohibit translations for this specific
  // navigation. For example, a user can select "never translate this language".
  // Mutates |decision| accordingly.
  void FilterForUserPrefs(TranslateTriggerDecision* decision,
                          TranslatePrefs* translate_prefs,
                          const std::string& page_language_code);

  // Determines if either auto-translation or showing the UI is supported for
  // the current navigation's hrefTranslate attribute. Writes the results to
  // |decision|.
  void FilterForHrefTranslate(TranslateTriggerDecision* decision,
                              TranslatePrefs* translate_prefs,
                              const std::string& page_language_code);

  // Determines if showing the UI is supported for the predefined target
  // language which was set via SetPredefinedTargetLanguage call.
  // Writes the results to |decision|.
  void FilterForPredefinedTarget(TranslateTriggerDecision* decision,
                                 TranslatePrefs* translate_prefs,
                                 const std::string& page_language_code);

  // See description of the public |GetTargetLanguage|. This is the actual
  // implementation that also takes a reference to |target_language_origin| for
  // logging.
  static std::string GetTargetLanguage(
      TranslatePrefs* prefs,
      language::LanguageModel* language_model,
      const std::string source_lang_code,
      TranslateBrowserMetrics::TargetLanguageOrigin& target_language_origin);

  // Enables or disables the translate omnibox icon depending on |decision|. The
  // icon is always shown if translate UI is shown, auto-translation happens, or
  // the UI is suppressed by ranker.
  void MaybeShowOmniboxIcon(const TranslateTriggerDecision& decision);

  // Shows the UI or auto-translates based on the state of |decision|. Returns
  // true if UI was shown, false otherwise.
  bool MaterializeDecision(const TranslateTriggerDecision& decision,
                           TranslatePrefs* translate_prefs,
                           const std::string& page_language_code,
                           const std::string target_lang);

  // Records all UMA metrics related to the current |decision|.
  void RecordDecisionMetrics(const TranslateTriggerDecision& decision,
                             const std::string& page_language_code,
                             bool ui_shown);

  // Records the RankerEvent associated with the current |decision|.
  void RecordDecisionRankerEvent(const TranslateTriggerDecision& decision,
                                 TranslatePrefs* translate_prefs,
                                 const std::string& page_language_code,
                                 const std::string& target_lang);

  // Sequence number of the current page.
  int page_seq_no_;

  raw_ptr<TranslateClient> translate_client_;        // Weak.
  raw_ptr<TranslateDriver> translate_driver_;        // Weak.
  raw_ptr<TranslateRanker> translate_ranker_;        // Weak.
  raw_ptr<language::LanguageModel> language_model_;  // Weak.

  base::WeakPtr<TranslateMetricsLogger> active_translate_metrics_logger_;
  std::unique_ptr<NullTranslateMetricsLogger> null_translate_metrics_logger_;

  LanguageState language_state_;

  std::unique_ptr<metrics::TranslateEventProto> translate_event_;

  base::WeakPtrFactory<TranslateManager> weak_method_factory_{this};

  // By default, don't offer to translate in builds lacking an API key. For
  // testing, set to true to offer anyway.
  static bool ignore_missing_key_for_testing_;
};

}  // namespace translate

#endif  // COMPONENTS_TRANSLATE_CORE_BROWSER_TRANSLATE_MANAGER_H_