File: translate_message.h

package info (click to toggle)
chromium 139.0.7258.127-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,122,156 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 (177 lines) | stat: -rw-r--r-- 6,699 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
// Copyright 2022 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_CONTENT_ANDROID_TRANSLATE_MESSAGE_H_
#define COMPONENTS_TRANSLATE_CONTENT_ANDROID_TRANSLATE_MESSAGE_H_

#include <jni.h>

#include <memory>
#include <string>

#include "base/android/scoped_java_ref.h"
#include "base/containers/span.h"
#include "base/feature_list.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "components/translate/core/browser/translate_step.h"

namespace content {
class WebContents;
}

namespace translate {

class TranslateManager;
class TranslateUIDelegate;
class TranslateUILanguagesManager;

class TranslateMessage {
 public:
  TranslateMessage(content::WebContents* web_contents,
                   const base::WeakPtr<TranslateManager>& translate_manager,
                   base::RepeatingCallback<void()> on_dismiss_callback);

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

  // Dismiss message on destruction if it is shown.
  ~TranslateMessage();

  // Show the Translate message UI in the specified state, or update an
  // existing visible message to have the specified state if one is already
  // visible.
  void ShowTranslateStep(TranslateStep step,
                         const std::string& source_language,
                         const std::string& target_language);

  // Called by Java in response to the user clicking the primary button.
  void HandlePrimaryAction(JNIEnv* env);
  // Called by Java in response to the message being dismissed.
  void HandleDismiss(JNIEnv* env, jint dismiss_reason);

  // Called by Java in order to build the secondary overflow menu.
  base::android::ScopedJavaLocalRef<jobjectArray> BuildOverflowMenu(
      JNIEnv* env);

  // Called by Java in response to a secondary menu item being clicked. A
  // non-null return value means that another secondary menu with the returned
  // list of menu items should be shown immediately, e.g. in order to show a
  // language picker menu. The |overflow_menu_item_id| will indicate which
  // overflow menu item that this click is related to, and the |language_code|
  // indicates which language was clicked in a language picker menu (or the
  // empty string if this was the overflow menu).
  //
  // For example, if the user clicks "More languages" on the overflow menu, then
  // |overflow_menu_item_id| would be kChangeTargetLanguage, and |language_code|
  // would be an empty string. If the user clicks "French" on the "More
  // languages" language picker menu, then |overflow_menu_item_id| would be
  // kChangeTargetLanguage and |language_code| would be "fr".
  base::android::ScopedJavaLocalRef<jobjectArray>
  HandleSecondaryMenuItemClicked(
      JNIEnv* env,
      jint overflow_menu_item_id,
      const base::android::JavaRef<jstring>& language_code,
      jboolean had_checkmark);

  // Passes on JNI calls to the stored Java TranslateMessage object, if
  // applicable. This interface exists in order to make it easier to test
  // TranslateMessage.
  class Bridge {
   public:
    virtual ~Bridge();

    // A raw content::WebContents pointer is passed in instead of the Java
    // WebContents object in order to make testing easier, so that tests can
    // just use nullptr as the content::WebContents.
    virtual bool CreateTranslateMessage(
        JNIEnv* env,
        content::WebContents* web_contents,
        TranslateMessage* native_translate_message,
        jint dismissal_duration_seconds) = 0;

    virtual void ShowTranslateError(JNIEnv* env,
                                    content::WebContents* web_contents) = 0;

    virtual void ShowMessage(
        JNIEnv* env,
        base::android::ScopedJavaLocalRef<jstring> title,
        base::android::ScopedJavaLocalRef<jstring> description,
        base::android::ScopedJavaLocalRef<jstring> primary_button_text,
        jboolean has_overflow_menu) = 0;

    virtual base::android::ScopedJavaLocalRef<jobjectArray>
    ConstructMenuItemArray(
        JNIEnv* env,
        base::android::ScopedJavaLocalRef<jobjectArray> titles,
        base::android::ScopedJavaLocalRef<jobjectArray> subtitles,
        base::android::ScopedJavaLocalRef<jbooleanArray> has_checkmarks,
        base::android::ScopedJavaLocalRef<jintArray> overflow_menu_item_ids,
        base::android::ScopedJavaLocalRef<jobjectArray> language_codes) = 0;

    virtual void ClearNativePointer(JNIEnv* env) = 0;
    virtual void Dismiss(JNIEnv* env) = 0;
  };

  // Test-only constructor with a custom JavaMethodCaller.
  TranslateMessage(content::WebContents* web_contents,
                   const base::WeakPtr<TranslateManager>& translate_manager,
                   base::RepeatingCallback<void()> on_dismiss_callback,
                   std::unique_ptr<Bridge> bridge);

  // This enum is only visible for testing purposes - the Java TranslateMessage
  // treats these ids as opaque integers.
  enum class OverflowMenuItemId {
    kInvalid,
    kChangeSourceLanguage,
    kChangeTargetLanguage,
    kToggleAlwaysTranslateLanguage,
    kToggleNeverTranslateLanguage,
    kToggleNeverTranslateSite,
  };

 private:
  enum class State {
    kDismissed,

    kBeforeTranslate,
    kTranslating,
    kAfterTranslate,

    kAfterTranslateWithAutoAlwaysConfirmation,
    kAutoNeverTranslateConfirmation,
  };

  void RevertTranslationAndUpdateMessage();

  base::android::ScopedJavaLocalRef<jobjectArray> ConstructLanguagePickerMenu(
      JNIEnv* env,
      OverflowMenuItemId overflow_menu_item_id,
      base::span<const std::string> content_language_codes,
      base::span<const std::string> skip_language_codes) const;

  raw_ptr<content::WebContents> web_contents_;
  base::WeakPtr<TranslateManager> translate_manager_;
  base::RepeatingCallback<void()> on_dismiss_callback_;

  std::unique_ptr<Bridge> bridge_;

  // Constructed the first time ShowTranslateStep is called.
  std::unique_ptr<TranslateUIDelegate> ui_delegate_;
  raw_ptr<TranslateUILanguagesManager> ui_languages_manager_;
  State state_ = State::kDismissed;

  // Keeps track of whether or not this TranslateMessage has ever been
  // interacted with in any way aside from dismissing it.
  bool has_been_interacted_with_ = false;

  // Keeps track of whether or not a translation is in progress that could
  // trigger automatically setting "always translate language".
  bool is_translation_eligible_for_auto_always_translate_ = false;
};

}  // namespace translate

#endif  // COMPONENTS_TRANSLATE_CONTENT_ANDROID_TRANSLATE_MESSAGE_H_