#include "base/metrics/histogram.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/infobars/infobar.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/translate/translate_accept_languages.h"
#include "chrome/browser/translate/translate_manager.h"
#include "chrome/browser/translate/translate_tab_helper.h"
-#include "components/translate/common/translate_constants.h"
+#include "components/translate/core/browser/translate_accept_languages.h"
+#include "components/translate/core/browser/translate_download_manager.h"
+#include "components/translate/core/common/translate_constants.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/web_contents.h"
#include "third_party/icu/source/i18n/unicode/coll.h"
#include "ui/base/l10n/l10n_util.h"
-using content::NavigationEntry;
-
namespace {
-// TODO(hajimehoshi): Remove this after crbug/283720 is solved.
-const char kDeclineTranslate[] = "Translate.DeclineTranslate";
-
-const char kCloseInfobar[] = "Translate.DeclineTranslateCloseInfobar";
-const char kShowErrorInfobar[] = "Translate.ShowErrorInfobar";
+// Counts used to decide whether infobars should be shown.
+// Android and iOS implementations do not offer a drop down (for space reasons),
+// so we are more aggressive about showing the shortcut to never translate.
+// The "Always Translate" option is always shown on iOS and Android.
+#if defined(OS_ANDROID)
+ const int kAlwaysTranslateMinCount = 1;
+ const int kNeverTranslateMinCount = 1;
+#elif defined(OS_IOS)
+ // The iOS implementation, like the Android implementation, shows the "Never
+ // translate" infobar after two denials. There is an offset of one because on
+ // Android the last event is not counted.
+ const int kAlwaysTranslateMinCount = 1;
+ const int kNeverTranslateMinCount = 2;
+#else
+ const int kAlwaysTranslateMinCount = 3;
+ const int kNeverTranslateMinCount = 3;
+#endif
} // namespace
}
// static
-void TranslateInfoBarDelegate::Create(
- bool replace_existing_infobar,
- InfoBarService* infobar_service,
- Type infobar_type,
- const std::string& original_language,
- const std::string& target_language,
- TranslateErrors::Type error_type,
- PrefService* prefs,
- const ShortcutConfiguration& shortcut_config) {
+void TranslateInfoBarDelegate::Create(bool replace_existing_infobar,
+ content::WebContents* web_contents,
+ TranslateTabHelper::TranslateStep step,
+ const std::string& original_language,
+ const std::string& target_language,
+ TranslateErrors::Type error_type,
+ PrefService* prefs) {
// Check preconditions.
- if (infobar_type != TRANSLATION_ERROR) {
- DCHECK(TranslateManager::IsSupportedLanguage(target_language));
- if (!TranslateManager::IsSupportedLanguage(original_language)) {
+ if (step != TranslateTabHelper::TRANSLATE_ERROR) {
+ DCHECK(TranslateDownloadManager::IsSupportedLanguage(target_language));
+ if (!TranslateDownloadManager::IsSupportedLanguage(original_language)) {
// The original language can only be "unknown" for the "translating"
// infobar, which is the case when the user started a translation from the
// context menu.
- DCHECK(infobar_type == TRANSLATING || infobar_type == AFTER_TRANSLATE);
+ DCHECK(step == TranslateTabHelper::TRANSLATING ||
+ step == TranslateTabHelper::AFTER_TRANSLATE);
DCHECK_EQ(translate::kUnknownLanguageCode, original_language);
}
}
+ // Do not create the after translate infobar if we are auto translating.
+ if ((step == TranslateTabHelper::AFTER_TRANSLATE) ||
+ (step == TranslateTabHelper::TRANSLATING)) {
+ TranslateTabHelper* translate_tab_helper =
+ TranslateTabHelper::FromWebContents(web_contents);
+ if (!translate_tab_helper ||
+ translate_tab_helper->GetLanguageState().InTranslateNavigation())
+ return;
+ }
+
// Find any existing translate infobar delegate.
+ InfoBar* old_infobar = NULL;
+ InfoBarService* infobar_service =
+ InfoBarService::FromWebContents(web_contents);
TranslateInfoBarDelegate* old_delegate = NULL;
for (size_t i = 0; i < infobar_service->infobar_count(); ++i) {
- old_delegate = infobar_service->infobar_at(i)->AsTranslateInfoBarDelegate();
+ old_infobar = infobar_service->infobar_at(i);
+ old_delegate = old_infobar->delegate()->AsTranslateInfoBarDelegate();
if (old_delegate) {
if (!replace_existing_infobar)
return;
}
}
- // Create the new delegate.
- scoped_ptr<TranslateInfoBarDelegate> infobar(
- new TranslateInfoBarDelegate(infobar_service, infobar_type, old_delegate,
- original_language, target_language,
- error_type, prefs, shortcut_config));
-
- // Do not create the after translate infobar if we are auto translating.
- if ((infobar_type == TranslateInfoBarDelegate::AFTER_TRANSLATE) ||
- (infobar_type == TranslateInfoBarDelegate::TRANSLATING)) {
- TranslateTabHelper* translate_tab_helper =
- TranslateTabHelper::FromWebContents(infobar_service->web_contents());
- if (!translate_tab_helper ||
- translate_tab_helper->language_state().InTranslateNavigation())
- return;
- }
-
- // Add the new delegate if necessary.
- if (!old_delegate) {
- infobar_service->AddInfoBar(infobar.PassAs<InfoBarDelegate>());
- } else {
- DCHECK(replace_existing_infobar);
- infobar_service->ReplaceInfoBar(old_delegate,
- infobar.PassAs<InfoBarDelegate>());
- }
+ // Add the new delegate.
+ scoped_ptr<InfoBar> infobar(CreateInfoBar(
+ scoped_ptr<TranslateInfoBarDelegate>(new TranslateInfoBarDelegate(
+ web_contents, step, old_delegate, original_language,
+ target_language, error_type, prefs))));
+ if (old_delegate)
+ infobar_service->ReplaceInfoBar(old_infobar, infobar.Pass());
+ else
+ infobar_service->AddInfoBar(infobar.Pass());
}
void TranslateInfoBarDelegate::RevertTranslation() {
ui_delegate_.RevertTranslation();
- RemoveSelf();
+ infobar()->RemoveSelf();
}
void TranslateInfoBarDelegate::ReportLanguageDetectionError() {
}
void TranslateInfoBarDelegate::TranslationDeclined() {
- // TODO(miguelg) switch this back to just calling web_contents()
- // once we've diagnosed crbug/283720
- // TODO(hajimehoshi): Replace this implementstion with calling ui_delegate_.
- // TranslationDeclined() after miguelg's investigating.
- content::WebContents* contents = owner()->web_contents();
- content::BrowserContext* context = contents->GetBrowserContext();
- if (!context->IsOffTheRecord()) {
- prefs_.ResetTranslationAcceptedCount(original_language_code());
- prefs_.IncrementTranslationDeniedCount(original_language_code());
- }
-
- // Remember that the user declined the translation so as to prevent showing a
- // translate infobar for that page again. (TranslateManager initiates
- // translations when getting a LANGUAGE_DETERMINED from the page, which
- // happens when a load stops. That could happen multiple times, including
- // after the user already declined the translation.)
- TranslateTabHelper::FromWebContents(web_contents())->
- language_state().set_translation_declined(true);
-
- UMA_HISTOGRAM_BOOLEAN(kDeclineTranslate, true);
+ ui_delegate_.TranslationDeclined(false);
}
bool TranslateInfoBarDelegate::IsTranslatableLanguageByPrefs() {
Profile* profile =
Profile::FromBrowserContext(web_contents()->GetBrowserContext());
Profile* original_profile = profile->GetOriginalProfile();
- return TranslatePrefs::CanTranslateLanguage(original_profile,
- original_language_code());
+ scoped_ptr<TranslatePrefs> translate_prefs(
+ TranslateTabHelper::CreateTranslatePrefs(original_profile->GetPrefs()));
+ TranslateAcceptLanguages* accept_languages =
+ TranslateTabHelper::GetTranslateAcceptLanguages(original_profile);
+ return translate_prefs->CanTranslateLanguage(accept_languages,
+ original_language_code());
}
void TranslateInfoBarDelegate::ToggleTranslatableLanguageByPrefs() {
ui_delegate_.SetLanguageBlocked(false);
} else {
ui_delegate_.SetLanguageBlocked(true);
- RemoveSelf();
+ infobar()->RemoveSelf();
}
}
ui_delegate_.SetSiteBlacklist(false);
} else {
ui_delegate_.SetSiteBlacklist(true);
- RemoveSelf();
+ infobar()->RemoveSelf();
}
}
void TranslateInfoBarDelegate::NeverTranslatePageLanguage() {
DCHECK(!ui_delegate_.IsLanguageBlocked());
ui_delegate_.SetLanguageBlocked(true);
- RemoveSelf();
+ infobar()->RemoveSelf();
}
-string16 TranslateInfoBarDelegate::GetMessageInfoBarText() {
- if (infobar_type_ == TRANSLATING) {
- string16 target_language_name = language_name_at(target_language_index());
+base::string16 TranslateInfoBarDelegate::GetMessageInfoBarText() {
+ if (step_ == TranslateTabHelper::TRANSLATING) {
+ base::string16 target_language_name =
+ language_name_at(target_language_index());
return l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_TRANSLATING_TO,
target_language_name);
}
- DCHECK_EQ(TRANSLATION_ERROR, infobar_type_);
- UMA_HISTOGRAM_ENUMERATION(kShowErrorInfobar,
+ DCHECK_EQ(TranslateTabHelper::TRANSLATE_ERROR, step_);
+ UMA_HISTOGRAM_ENUMERATION("Translate.ShowErrorInfobar",
error_type_,
TranslateErrors::TRANSLATE_ERROR_MAX);
+ ui_delegate_.OnErrorShown(error_type_);
switch (error_type_) {
case TranslateErrors::NETWORK:
return l10n_util::GetStringUTF16(
language_name_at(target_language_index()));
default:
NOTREACHED();
- return string16();
+ return base::string16();
}
}
-string16 TranslateInfoBarDelegate::GetMessageInfoBarButtonText() {
- if (infobar_type_ != TRANSLATION_ERROR) {
- DCHECK_EQ(TRANSLATING, infobar_type_);
+base::string16 TranslateInfoBarDelegate::GetMessageInfoBarButtonText() {
+ if (step_ != TranslateTabHelper::TRANSLATE_ERROR) {
+ DCHECK_EQ(TranslateTabHelper::TRANSLATING, step_);
} else if ((error_type_ != TranslateErrors::IDENTICAL_LANGUAGES) &&
(error_type_ != TranslateErrors::UNKNOWN_LANGUAGE)) {
return l10n_util::GetStringUTF16(
(error_type_ == TranslateErrors::UNSUPPORTED_LANGUAGE) ?
IDS_TRANSLATE_INFOBAR_REVERT : IDS_TRANSLATE_INFOBAR_RETRY);
}
- return string16();
+ return base::string16();
}
void TranslateInfoBarDelegate::MessageInfoBarButtonPressed() {
- DCHECK_EQ(TRANSLATION_ERROR, infobar_type_);
+ DCHECK_EQ(TranslateTabHelper::TRANSLATE_ERROR, step_);
if (error_type_ == TranslateErrors::UNSUPPORTED_LANGUAGE) {
RevertTranslation();
return;
}
bool TranslateInfoBarDelegate::ShouldShowNeverTranslateShortcut() {
- DCHECK_EQ(BEFORE_TRANSLATE, infobar_type_);
+ DCHECK_EQ(TranslateTabHelper::BEFORE_TRANSLATE, step_);
return !web_contents()->GetBrowserContext()->IsOffTheRecord() &&
- (prefs_.GetTranslationDeniedCount(original_language_code()) >=
- shortcut_config_.never_translate_min_count);
+ (prefs_->GetTranslationDeniedCount(original_language_code()) >=
+ kNeverTranslateMinCount);
}
bool TranslateInfoBarDelegate::ShouldShowAlwaysTranslateShortcut() {
- DCHECK_EQ(BEFORE_TRANSLATE, infobar_type_);
+ DCHECK_EQ(TranslateTabHelper::BEFORE_TRANSLATE, step_);
return !web_contents()->GetBrowserContext()->IsOffTheRecord() &&
- (prefs_.GetTranslationAcceptedCount(original_language_code()) >=
- shortcut_config_.always_translate_min_count);
+ (prefs_->GetTranslationAcceptedCount(original_language_code()) >=
+ kAlwaysTranslateMinCount);
}
// static
-string16 TranslateInfoBarDelegate::GetLanguageDisplayableName(
+base::string16 TranslateInfoBarDelegate::GetLanguageDisplayableName(
const std::string& language_code) {
return l10n_util::GetDisplayNameForLocale(
language_code, g_browser_process->GetApplicationLocale(), true);
// static
void TranslateInfoBarDelegate::GetAfterTranslateStrings(
- std::vector<string16>* strings,
+ std::vector<base::string16>* strings,
bool* swap_languages,
bool autodetermined_source_language) {
DCHECK(strings);
if (autodetermined_source_language) {
size_t offset;
- string16 text = l10n_util::GetStringFUTF16(
+ base::string16 text = l10n_util::GetStringFUTF16(
IDS_TRANSLATE_INFOBAR_AFTER_MESSAGE_AUTODETERMINED_SOURCE_LANGUAGE,
- string16(),
+ base::string16(),
&offset);
strings->push_back(text.substr(0, offset));
DCHECK(swap_languages);
std::vector<size_t> offsets;
- string16 text = l10n_util::GetStringFUTF16(
- IDS_TRANSLATE_INFOBAR_AFTER_MESSAGE, string16(), string16(), &offsets);
+ base::string16 text = l10n_util::GetStringFUTF16(
+ IDS_TRANSLATE_INFOBAR_AFTER_MESSAGE, base::string16(), base::string16(),
+ &offsets);
DCHECK_EQ(2U, offsets.size());
*swap_languages = (offsets[0] > offsets[1]);
}
TranslateInfoBarDelegate::TranslateInfoBarDelegate(
- InfoBarService* infobar_service,
- Type infobar_type,
+ content::WebContents* web_contents,
+ TranslateTabHelper::TranslateStep step,
TranslateInfoBarDelegate* old_delegate,
const std::string& original_language,
const std::string& target_language,
TranslateErrors::Type error_type,
- PrefService* prefs,
- ShortcutConfiguration shortcut_config)
- : InfoBarDelegate(infobar_service),
- infobar_type_(infobar_type),
+ PrefService* prefs)
+ : InfoBarDelegate(),
+ step_(step),
background_animation_(NONE),
- ui_delegate_(web_contents(), original_language, target_language),
+ ui_delegate_(web_contents, original_language, target_language),
error_type_(error_type),
- prefs_(prefs),
- shortcut_config_(shortcut_config) {
- DCHECK_NE((infobar_type_ == TRANSLATION_ERROR),
+ prefs_(TranslateTabHelper::CreateTranslatePrefs(prefs)) {
+ DCHECK_NE((step_ == TranslateTabHelper::TRANSLATE_ERROR),
(error_type_ == TranslateErrors::NONE));
if (old_delegate && (old_delegate->is_error() != is_error()))
background_animation_ = is_error() ? NORMAL_TO_ERROR : ERROR_TO_NORMAL;
}
+// TranslateInfoBarDelegate::CreateInfoBar() is implemented in platform-specific
+// files.
+
void TranslateInfoBarDelegate::InfoBarDismissed() {
- if (infobar_type_ != BEFORE_TRANSLATE)
+ if (step_ != TranslateTabHelper::BEFORE_TRANSLATE)
return;
// The user closed the infobar without clicking the translate button.
TranslationDeclined();
- UMA_HISTOGRAM_BOOLEAN(kCloseInfobar, true);
+ UMA_HISTOGRAM_BOOLEAN("Translate.DeclineTranslateCloseInfobar", true);
}
int TranslateInfoBarDelegate::GetIconID() const {