translate_compact_infobar.cc 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "weblayer/browser/translate_compact_infobar.h"
  5. #include <stddef.h>
  6. #include <memory>
  7. #include "base/android/jni_android.h"
  8. #include "base/android/jni_array.h"
  9. #include "base/android/jni_string.h"
  10. #include "base/android/jni_weak_ref.h"
  11. #include "base/bind.h"
  12. #include "components/infobars/content/content_infobar_manager.h"
  13. #include "components/translate/content/android/translate_utils.h"
  14. #include "components/translate/core/browser/translate_infobar_delegate.h"
  15. #include "components/variations/variations_associated_data.h"
  16. #include "content/public/browser/browser_context.h"
  17. #include "weblayer/browser/java/jni/TranslateCompactInfoBar_jni.h"
  18. #include "weblayer/browser/tab_impl.h"
  19. #include "weblayer/browser/translate_client_impl.h"
  20. using base::android::JavaParamRef;
  21. using base::android::ScopedJavaLocalRef;
  22. namespace weblayer {
  23. // Finch parameter names:
  24. const char kTranslateTabDefaultTextColor[] = "translate_tab_default_text_color";
  25. // TranslateInfoBar -----------------------------------------------------------
  26. TranslateCompactInfoBar::TranslateCompactInfoBar(
  27. std::unique_ptr<translate::TranslateInfoBarDelegate> delegate)
  28. : infobars::InfoBarAndroid(std::move(delegate)), action_flags_(FLAG_NONE) {
  29. GetDelegate()->AddObserver(this);
  30. // Flip the translate bit if auto translate is enabled.
  31. if (GetDelegate()->translate_step() == translate::TRANSLATE_STEP_TRANSLATING)
  32. action_flags_ |= FLAG_TRANSLATE;
  33. }
  34. TranslateCompactInfoBar::~TranslateCompactInfoBar() {
  35. GetDelegate()->RemoveObserver(this);
  36. }
  37. ScopedJavaLocalRef<jobject> TranslateCompactInfoBar::CreateRenderInfoBar(
  38. JNIEnv* env,
  39. const ResourceIdMapper& resource_id_mapper) {
  40. translate::TranslateInfoBarDelegate* delegate = GetDelegate();
  41. translate::JavaLanguageInfoWrapper translate_languages =
  42. translate::TranslateUtils::GetTranslateLanguagesInJavaFormat(env,
  43. delegate);
  44. ScopedJavaLocalRef<jstring> source_language_code =
  45. base::android::ConvertUTF8ToJavaString(env,
  46. delegate->source_language_code());
  47. ScopedJavaLocalRef<jstring> target_language_code =
  48. base::android::ConvertUTF8ToJavaString(env,
  49. delegate->target_language_code());
  50. content::WebContents* web_contents =
  51. infobars::ContentInfoBarManager::WebContentsFromInfoBar(this);
  52. TabImpl* tab =
  53. web_contents ? TabImpl::FromWebContents(web_contents) : nullptr;
  54. return Java_TranslateCompactInfoBar_create(
  55. env, tab ? tab->GetJavaTab() : nullptr, delegate->translate_step(),
  56. source_language_code, target_language_code,
  57. delegate->ShouldNeverTranslateLanguage(),
  58. delegate->IsSiteOnNeverPromptList(), delegate->ShouldAlwaysTranslate(),
  59. delegate->triggered_from_menu(), translate_languages.java_languages,
  60. translate_languages.java_codes, translate_languages.java_hash_codes,
  61. TabDefaultTextColor());
  62. }
  63. void TranslateCompactInfoBar::ProcessButton(int action) {
  64. if (!owner())
  65. return; // We're closing; don't call anything, it might access the owner.
  66. translate::TranslateInfoBarDelegate* delegate = GetDelegate();
  67. if (action == infobars::InfoBarAndroid::ACTION_TRANSLATE) {
  68. action_flags_ |= FLAG_TRANSLATE;
  69. delegate->Translate();
  70. if (delegate->ShouldAutoAlwaysTranslate()) {
  71. JNIEnv* env = base::android::AttachCurrentThread();
  72. Java_TranslateCompactInfoBar_setAutoAlwaysTranslate(env,
  73. GetJavaInfoBar());
  74. }
  75. } else if (action ==
  76. infobars::InfoBarAndroid::ACTION_TRANSLATE_SHOW_ORIGINAL) {
  77. action_flags_ |= FLAG_REVERT;
  78. delegate->RevertWithoutClosingInfobar();
  79. } else {
  80. DCHECK_EQ(infobars::InfoBarAndroid::ACTION_NONE, action);
  81. }
  82. }
  83. void TranslateCompactInfoBar::SetJavaInfoBar(
  84. const base::android::JavaRef<jobject>& java_info_bar) {
  85. infobars::InfoBarAndroid::SetJavaInfoBar(java_info_bar);
  86. JNIEnv* env = base::android::AttachCurrentThread();
  87. Java_TranslateCompactInfoBar_setNativePtr(env, java_info_bar,
  88. reinterpret_cast<intptr_t>(this));
  89. }
  90. void TranslateCompactInfoBar::ApplyStringTranslateOption(
  91. JNIEnv* env,
  92. const JavaParamRef<jobject>& obj,
  93. int option,
  94. const JavaParamRef<jstring>& value) {
  95. translate::TranslateInfoBarDelegate* delegate = GetDelegate();
  96. if (option == translate::TranslateUtils::OPTION_SOURCE_CODE) {
  97. std::string source_code =
  98. base::android::ConvertJavaStringToUTF8(env, value);
  99. if (delegate->source_language_code().compare(source_code) != 0)
  100. delegate->UpdateSourceLanguage(source_code);
  101. } else if (option == translate::TranslateUtils::OPTION_TARGET_CODE) {
  102. std::string target_code =
  103. base::android::ConvertJavaStringToUTF8(env, value);
  104. if (delegate->target_language_code().compare(target_code) != 0)
  105. delegate->UpdateTargetLanguage(target_code);
  106. } else {
  107. DCHECK(false);
  108. }
  109. }
  110. void TranslateCompactInfoBar::ApplyBoolTranslateOption(
  111. JNIEnv* env,
  112. const JavaParamRef<jobject>& obj,
  113. int option,
  114. jboolean value) {
  115. translate::TranslateInfoBarDelegate* delegate = GetDelegate();
  116. if (option == translate::TranslateUtils::OPTION_ALWAYS_TRANSLATE) {
  117. if (delegate->ShouldAlwaysTranslate() != value) {
  118. action_flags_ |= FLAG_ALWAYS_TRANSLATE;
  119. delegate->ToggleAlwaysTranslate();
  120. }
  121. } else if (option == translate::TranslateUtils::OPTION_NEVER_TRANSLATE) {
  122. bool language_blocklisted = !delegate->IsTranslatableLanguageByPrefs();
  123. if (language_blocklisted != value) {
  124. delegate->RevertWithoutClosingInfobar();
  125. action_flags_ |= FLAG_NEVER_LANGUAGE;
  126. delegate->ToggleTranslatableLanguageByPrefs();
  127. }
  128. } else if (option == translate::TranslateUtils::OPTION_NEVER_TRANSLATE_SITE) {
  129. if (delegate->IsSiteOnNeverPromptList() != value) {
  130. delegate->RevertWithoutClosingInfobar();
  131. action_flags_ |= FLAG_NEVER_SITE;
  132. delegate->ToggleNeverPromptSite();
  133. }
  134. } else {
  135. DCHECK(false);
  136. }
  137. }
  138. jboolean TranslateCompactInfoBar::ShouldAutoNeverTranslate(
  139. JNIEnv* env,
  140. const base::android::JavaParamRef<jobject>& obj,
  141. jboolean menu_expanded) {
  142. // Flip menu expanded bit.
  143. if (menu_expanded)
  144. action_flags_ |= FLAG_EXPAND_MENU;
  145. if (!IsDeclinedByUser())
  146. return false;
  147. return GetDelegate()->ShouldAutoNeverTranslate();
  148. }
  149. // Returns true if the current tab is an incognito tab.
  150. jboolean TranslateCompactInfoBar::IsIncognito(
  151. JNIEnv* env,
  152. const base::android::JavaParamRef<jobject>& obj) {
  153. content::WebContents* web_contents =
  154. infobars::ContentInfoBarManager::WebContentsFromInfoBar(this);
  155. if (!web_contents)
  156. return false;
  157. return web_contents->GetBrowserContext()->IsOffTheRecord();
  158. }
  159. int TranslateCompactInfoBar::GetParam(const std::string& paramName,
  160. int default_value) {
  161. std::map<std::string, std::string> params;
  162. if (!variations::GetVariationParams(translate::kTranslateCompactUI.name,
  163. &params))
  164. return default_value;
  165. int value = 0;
  166. base::StringToInt(params[paramName], &value);
  167. return value <= 0 ? default_value : value;
  168. }
  169. int TranslateCompactInfoBar::TabDefaultTextColor() {
  170. return GetParam(kTranslateTabDefaultTextColor, 0);
  171. }
  172. translate::TranslateInfoBarDelegate* TranslateCompactInfoBar::GetDelegate() {
  173. return delegate()->AsTranslateInfoBarDelegate();
  174. }
  175. void TranslateCompactInfoBar::OnTranslateStepChanged(
  176. translate::TranslateStep step,
  177. translate::TranslateErrors::Type error_type) {
  178. // If the tab lost active state while translation was occurring, the Java
  179. // infobar will now be gone. In that case there is nothing to do here.
  180. if (!HasSetJavaInfoBar())
  181. return; // No connected Java infobar
  182. if (!owner())
  183. return; // We're closing; don't call anything.
  184. if ((step == translate::TRANSLATE_STEP_AFTER_TRANSLATE) ||
  185. (step == translate::TRANSLATE_STEP_TRANSLATE_ERROR)) {
  186. JNIEnv* env = base::android::AttachCurrentThread();
  187. Java_TranslateCompactInfoBar_onPageTranslated(env, GetJavaInfoBar(),
  188. error_type);
  189. }
  190. }
  191. void TranslateCompactInfoBar::OnTargetLanguageChanged(
  192. const std::string& target_language_code) {
  193. // In WebLayer, target language changes are only initiated by the UI. This
  194. // method should always be a no-op.
  195. DCHECK_EQ(GetDelegate()->target_language_code(), target_language_code);
  196. }
  197. bool TranslateCompactInfoBar::IsDeclinedByUser() {
  198. // Whether there is any affirmative action bit.
  199. return action_flags_ == FLAG_NONE;
  200. }
  201. void TranslateCompactInfoBar::OnTranslateInfoBarDelegateDestroyed(
  202. translate::TranslateInfoBarDelegate* delegate) {
  203. DCHECK_EQ(GetDelegate(), delegate);
  204. GetDelegate()->RemoveObserver(this);
  205. }
  206. } // namespace weblayer