From 546f5d64e41e0b65f80e25d7f1e7b1e22d1203a8 Mon Sep 17 00:00:00 2001 From: "droger@chromium.org" Date: Mon, 10 Feb 2014 17:54:50 +0000 Subject: [PATCH] Move UI code out of TranslateManager The UI code is dependent on the embedder of Translate, and thus is moved out of TranslateManager (which is intended to deal only with core logic). The UI code is moved in TranslateTabHelper, which is the main embedder class for Translate. The |use_infobar_| global state is moved to TranslateService which is the singleton dealing with Translate global state. The ShortcutConfig class (related to translate infobars) is removed as it was not used. BUG=336249 TBR=jochen Review URL: https://codereview.chromium.org/136643009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@250142 0039d316-1c4b-4281-b951-d872f2087c98 --- .../autofill/autofill_interactive_uitest.cc | 4 +- chrome/browser/policy/policy_browsertest.cc | 4 +- chrome/browser/translate/translate_browsertest.cc | 4 +- .../translate/translate_infobar_delegate.cc | 49 ++++-- .../browser/translate/translate_infobar_delegate.h | 15 +- chrome/browser/translate/translate_manager.cc | 175 ++++----------------- chrome/browser/translate/translate_manager.h | 24 --- .../translate/translate_manager_browsertest.cc | 8 +- chrome/browser/translate/translate_service.cc | 25 ++- chrome/browser/translate/translate_service.h | 11 ++ chrome/browser/translate/translate_tab_helper.cc | 150 +++++++++++++++++- chrome/browser/translate/translate_tab_helper.h | 28 ++++ .../cocoa/infobars/translate_infobar_unittest.mm | 10 +- .../ui/views/location_bar/location_bar_view.cc | 4 +- 14 files changed, 291 insertions(+), 220 deletions(-) diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc index fd9e4098ccb6..3a2e180cd5f8 100644 --- a/chrome/browser/autofill/autofill_interactive_uitest.cc +++ b/chrome/browser/autofill/autofill_interactive_uitest.cc @@ -22,7 +22,7 @@ #include "chrome/browser/infobars/infobar_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/translate/translate_infobar_delegate.h" -#include "chrome/browser/translate/translate_manager.h" +#include "chrome/browser/translate/translate_service.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -205,7 +205,7 @@ class AutofillInteractiveTest : public InProcessBrowserTest { // InProcessBrowserTest: virtual void SetUpOnMainThread() OVERRIDE { - TranslateManager::SetUseInfobar(true); + TranslateService::SetUseInfobar(true); // Don't want Keychain coming up on Mac. test::DisableSystemServices(browser()->profile()); diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc index 577de12bbad8..ff2e9425fe83 100644 --- a/chrome/browser/policy/policy_browsertest.cc +++ b/chrome/browser/policy/policy_browsertest.cc @@ -59,7 +59,7 @@ #include "chrome/browser/search_engines/template_url_service.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/translate/translate_infobar_delegate.h" -#include "chrome/browser/translate/translate_manager.h" +#include "chrome/browser/translate/translate_service.h" #include "chrome/browser/translate/translate_tab_helper.h" #include "chrome/browser/ui/bookmarks/bookmark_bar.h" #include "chrome/browser/ui/browser.h" @@ -1876,7 +1876,7 @@ IN_PROC_BROWSER_TEST_F(PolicyTest, SavingBrowserHistoryDisabled) { // http://crbug.com/241691 PolicyTest.TranslateEnabled is failing regularly. IN_PROC_BROWSER_TEST_F(PolicyTest, DISABLED_TranslateEnabled) { - TranslateManager::SetUseInfobar(true); + TranslateService::SetUseInfobar(true); // Verifies that translate can be forced enabled or disabled by policy. diff --git a/chrome/browser/translate/translate_browsertest.cc b/chrome/browser/translate/translate_browsertest.cc index 2e7f7ad00c29..0f17fcb9f42e 100644 --- a/chrome/browser/translate/translate_browsertest.cc +++ b/chrome/browser/translate/translate_browsertest.cc @@ -10,7 +10,7 @@ #include "chrome/browser/infobars/infobar.h" #include "chrome/browser/infobars/infobar_service.h" #include "chrome/browser/translate/translate_infobar_delegate.h" -#include "chrome/browser/translate/translate_manager.h" +#include "chrome/browser/translate/translate_service.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/in_process_browser_test.h" @@ -54,7 +54,7 @@ class TranslateBrowserTest : public InProcessBrowserTest { infobar_service_(NULL) {} virtual void SetUpOnMainThread() OVERRIDE { - TranslateManager::SetUseInfobar(true); + TranslateService::SetUseInfobar(true); } virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { diff --git a/chrome/browser/translate/translate_infobar_delegate.cc b/chrome/browser/translate/translate_infobar_delegate.cc index c5fbc0187aa8..37e7ad75b423 100644 --- a/chrome/browser/translate/translate_infobar_delegate.cc +++ b/chrome/browser/translate/translate_infobar_delegate.cc @@ -26,6 +26,27 @@ #include "third_party/icu/source/i18n/unicode/coll.h" #include "ui/base/l10n/l10n_util.h" +namespace { + +// 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 const size_t TranslateInfoBarDelegate::kNoIndex = TranslateUIDelegate::NO_INDEX; @@ -33,15 +54,13 @@ TranslateInfoBarDelegate::~TranslateInfoBarDelegate() { } // static -void TranslateInfoBarDelegate::Create( - bool replace_existing_infobar, - content::WebContents* web_contents, - 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, + Type infobar_type, + const std::string& original_language, + const std::string& target_language, + TranslateErrors::Type error_type, + PrefService* prefs) { // Check preconditions. if (infobar_type != TRANSLATION_ERROR) { DCHECK(TranslateDownloadManager::IsSupportedLanguage(target_language)); @@ -83,7 +102,7 @@ void TranslateInfoBarDelegate::Create( scoped_ptr infobar(CreateInfoBar( scoped_ptr(new TranslateInfoBarDelegate( web_contents, infobar_type, old_delegate, original_language, - target_language, error_type, prefs, shortcut_config)))); + target_language, error_type, prefs)))); if (old_delegate) infobar_service->ReplaceInfoBar(old_infobar, infobar.Pass()); else @@ -238,14 +257,14 @@ bool TranslateInfoBarDelegate::ShouldShowNeverTranslateShortcut() { DCHECK_EQ(BEFORE_TRANSLATE, infobar_type_); return !web_contents()->GetBrowserContext()->IsOffTheRecord() && (prefs_.GetTranslationDeniedCount(original_language_code()) >= - shortcut_config_.never_translate_min_count); + kNeverTranslateMinCount); } bool TranslateInfoBarDelegate::ShouldShowAlwaysTranslateShortcut() { DCHECK_EQ(BEFORE_TRANSLATE, infobar_type_); return !web_contents()->GetBrowserContext()->IsOffTheRecord() && (prefs_.GetTranslationAcceptedCount(original_language_code()) >= - shortcut_config_.always_translate_min_count); + kAlwaysTranslateMinCount); } // static @@ -297,15 +316,13 @@ TranslateInfoBarDelegate::TranslateInfoBarDelegate( const std::string& original_language, const std::string& target_language, TranslateErrors::Type error_type, - PrefService* prefs, - ShortcutConfiguration shortcut_config) + PrefService* prefs) : InfoBarDelegate(), infobar_type_(infobar_type), background_animation_(NONE), ui_delegate_(web_contents, original_language, target_language), error_type_(error_type), - prefs_(prefs), - shortcut_config_(shortcut_config) { + prefs_(prefs) { DCHECK_NE((infobar_type_ == TRANSLATION_ERROR), (error_type_ == TranslateErrors::NONE)); diff --git a/chrome/browser/translate/translate_infobar_delegate.h b/chrome/browser/translate/translate_infobar_delegate.h index 35b894963739..ddb42ed1682d 100644 --- a/chrome/browser/translate/translate_infobar_delegate.h +++ b/chrome/browser/translate/translate_infobar_delegate.h @@ -19,13 +19,6 @@ class PrefService; -// The defaults after which extra shortcuts for options -// can be shown. -struct ShortcutConfiguration { - int always_translate_min_count; - int never_translate_min_count; -}; - class TranslateInfoBarDelegate : public InfoBarDelegate { public: // The different types of infobars that can be shown for translation. @@ -66,8 +59,7 @@ class TranslateInfoBarDelegate : public InfoBarDelegate { const std::string& original_language, const std::string& target_language, TranslateErrors::Type error_type, - PrefService* prefs, - const ShortcutConfiguration& shortcut_config); + PrefService* prefs); // Returns the number of languages supported. size_t num_languages() const { return ui_delegate_.GetNumberOfLanguages(); } @@ -179,8 +171,7 @@ class TranslateInfoBarDelegate : public InfoBarDelegate { const std::string& original_language, const std::string& target_language, TranslateErrors::Type error_type, - PrefService* prefs, - ShortcutConfiguration shortcut_config); + PrefService* prefs); private: friend class TranslationInfoBarTest; @@ -212,8 +203,6 @@ class TranslateInfoBarDelegate : public InfoBarDelegate { // The translation related preferences. TranslatePrefs prefs_; - // Translation shortcut configuration - ShortcutConfiguration shortcut_config_; DISALLOW_COPY_AND_ASSIGN(TranslateInfoBarDelegate); }; diff --git a/chrome/browser/translate/translate_manager.cc b/chrome/browser/translate/translate_manager.cc index ddb75976d3bc..1ffbc920883c 100644 --- a/chrome/browser/translate/translate_manager.cc +++ b/chrome/browser/translate/translate_manager.cc @@ -18,16 +18,12 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/tab_contents/tab_util.h" #include "chrome/browser/translate/translate_accept_languages.h" -#include "chrome/browser/translate/translate_infobar_delegate.h" #include "chrome/browser/translate/translate_prefs.h" #include "chrome/browser/translate/translate_tab_helper.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_tabstrip.h" -#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/ui/translate/translate_bubble_factory.h" -#include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/common/render_messages.h" #include "chrome/common/url_constants.h" @@ -87,9 +83,6 @@ TranslateManager::~TranslateManager() { } // static -bool TranslateManager::use_infobar_ = false; - -// static TranslateManager* TranslateManager::GetInstance() { return Singleton::get(); } @@ -362,20 +355,12 @@ void TranslateManager::InitiateTranslation(WebContents* web_contents, TranslateBrowserMetrics::ReportInitiationStatus( TranslateBrowserMetrics::INITIATION_STATUS_SHOW_INFOBAR); - if (IsTranslateBubbleEnabled()) { - language_state.SetTranslateEnabled(true); - if (language_state.HasLanguageChanged()) { - ShowBubble(web_contents, - TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE, - TranslateErrors::NONE); - } - } else { - // Prompts the user if he/she wants the page translated. - TranslateInfoBarDelegate::Create( - false, web_contents, TranslateInfoBarDelegate::BEFORE_TRANSLATE, - language_code, target_lang, TranslateErrors::NONE, profile->GetPrefs(), - ShortcutConfig()); - } + // Prompts the user if he/she wants the page translated. + translate_tab_helper->ShowTranslateUI(TranslateTabHelper::BEFORE_TRANSLATE, + web_contents, + language_code, + target_lang, + TranslateErrors::NONE); } void TranslateManager::InitiateTranslationPosted(int process_id, @@ -428,17 +413,14 @@ void TranslateManager::TranslatePage(WebContents* web_contents, if (!TranslateDownloadManager::IsSupportedLanguage(source_lang)) source_lang = std::string(translate::kUnknownLanguageCode); - if (IsTranslateBubbleEnabled()) { - ShowBubble(web_contents, TranslateBubbleModel::VIEW_STATE_TRANSLATING, - TranslateErrors::NONE); - } else { - Profile* profile = - Profile::FromBrowserContext(web_contents->GetBrowserContext()); - TranslateInfoBarDelegate::Create( - true, web_contents, TranslateInfoBarDelegate::TRANSLATING, source_lang, - target_lang, TranslateErrors::NONE, profile->GetPrefs(), - ShortcutConfig()); - } + TranslateTabHelper* translate_tab_helper = + TranslateTabHelper::FromWebContents(web_contents); + DCHECK(translate_tab_helper); + translate_tab_helper->ShowTranslateUI(TranslateTabHelper::TRANSLATING, + web_contents, + source_lang, + target_lang, + TranslateErrors::NONE); TranslateScript* script = TranslateDownloadManager::GetInstance()->script(); DCHECK(script != NULL); @@ -463,9 +445,8 @@ void TranslateManager::TranslatePage(WebContents* web_contents, if (script->HasPendingRequest()) return; - script->Request( - base::Bind(&TranslateManager::OnTranslateScriptFetchComplete, - base::Unretained(this))); + script->Request(base::Bind(&TranslateManager::OnTranslateScriptFetchComplete, + base::Unretained(this))); } void TranslateManager::RevertTranslation(WebContents* web_contents) { @@ -544,23 +525,14 @@ void TranslateManager::PageTranslated(WebContents* web_contents, details->error_type = TranslateErrors::UNSUPPORTED_LANGUAGE; } - if (IsTranslateBubbleEnabled()) { - TranslateBubbleModel::ViewState view_state = - (details->error_type == TranslateErrors::NONE) ? - TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE : - TranslateBubbleModel::VIEW_STATE_ERROR; - ShowBubble(web_contents, view_state, details->error_type); - } else { - PrefService* prefs = Profile::FromBrowserContext( - web_contents->GetBrowserContext())->GetPrefs(); - TranslateInfoBarDelegate::Create( - true, web_contents, - (details->error_type == TranslateErrors::NONE) ? - TranslateInfoBarDelegate::AFTER_TRANSLATE : - TranslateInfoBarDelegate::TRANSLATION_ERROR, - details->source_language, details->target_language, details->error_type, - prefs, ShortcutConfig()); - } + TranslateTabHelper* translate_tab_helper = + TranslateTabHelper::FromWebContents(web_contents); + DCHECK(translate_tab_helper); + translate_tab_helper->ShowTranslateUI(TranslateTabHelper::AFTER_TRANSLATE, + web_contents, + details->source_language, + details->target_language, + details->error_type); if (details->error_type != TranslateErrors::NONE && !web_contents->GetBrowserContext()->IsOffTheRecord()) { @@ -599,17 +571,14 @@ void TranslateManager::OnTranslateScriptFetchComplete( DoTranslatePage(web_contents, translate_script->data(), request.source_lang, request.target_lang); } else { - if (IsTranslateBubbleEnabled()) { - ShowBubble(web_contents, TranslateBubbleModel::VIEW_STATE_ERROR, - TranslateErrors::NETWORK); - } else { - Profile* profile = - Profile::FromBrowserContext(web_contents->GetBrowserContext()); - TranslateInfoBarDelegate::Create( - true, web_contents, TranslateInfoBarDelegate::TRANSLATION_ERROR, - request.source_lang, request.target_lang, TranslateErrors::NETWORK, - profile->GetPrefs(), ShortcutConfig()); - } + TranslateTabHelper* translate_tab_helper = + TranslateTabHelper::FromWebContents(web_contents); + DCHECK(translate_tab_helper); + translate_tab_helper->ShowTranslateUI(TranslateTabHelper::TRANSLATE_ERROR, + web_contents, + request.source_lang, + request.target_lang, + TranslateErrors::NETWORK); if (!web_contents->GetBrowserContext()->IsOffTheRecord()) { TranslateErrorDetails error_details; @@ -623,51 +592,6 @@ void TranslateManager::OnTranslateScriptFetchComplete( pending_requests_.clear(); } -void TranslateManager::ShowBubble(WebContents* web_contents, - TranslateBubbleModel::ViewState view_state, - TranslateErrors::Type error_type) { - // The bubble is implemented only on the desktop platforms. -#if !defined(OS_ANDROID) && !defined(OS_IOS) - Browser* browser = chrome::FindBrowserWithWebContents(web_contents); - - // |browser| might be NULL when testing. In this case, Show(...) should be - // called because the implementation for testing is used. - if (!browser) { - TranslateBubbleFactory::Show(NULL, web_contents, view_state, error_type); - return; - } - - if (web_contents != browser->tab_strip_model()->GetActiveWebContents()) - return; - - // This ShowBubble function is also used for upating the existing bubble. - // However, with the bubble shown, any browser windows are NOT activated - // because the bubble takes the focus from the other widgets including the - // browser windows. So it is checked that |browser| is the last activated - // browser, not is now activated. - if (browser != - chrome::FindLastActiveWithHostDesktopType(browser->host_desktop_type())) { - return; - } - - // During auto-translating, the bubble should not be shown. - if (view_state == TranslateBubbleModel::VIEW_STATE_TRANSLATING || - view_state == TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE) { - TranslateTabHelper* translate_tab_helper = - TranslateTabHelper::FromWebContents(web_contents); - if (!translate_tab_helper || - translate_tab_helper->GetLanguageState().InTranslateNavigation()) { - return; - } - } - - TranslateBubbleFactory::Show(browser->window(), web_contents, view_state, - error_type); -#else - NOTREACHED(); -#endif -} - // static std::string TranslateManager::GetTargetLanguage(PrefService* prefs) { std::string ui_lang = TranslatePrefs::ConvertLangCodeForTranslation( @@ -711,38 +635,3 @@ std::string TranslateManager::GetAutoTargetLanguage( } return std::string(); } - -// static -bool TranslateManager::IsTranslateBubbleEnabled() { -#if defined(USE_AURA) - return !use_infobar_; -#elif defined(OS_MACOSX) - // The bubble UX is experimental on Mac OS X. - return CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableTranslateNewUX); -#else - // The bubble UX is not implemented on the non-Aura platforms. - return false; -#endif -} - -// static -void TranslateManager::SetUseInfobar(bool value) { - use_infobar_ = value; -} - -// static -ShortcutConfiguration TranslateManager::ShortcutConfig() { - ShortcutConfiguration config; - - // The android implementation does not offer a drop down (for space reasons), - // so we are more aggressive about showing the shortcut to never translate. - #if defined(OS_ANDROID) - config.never_translate_min_count = 1; - #else - config.never_translate_min_count = 3; - #endif // defined(OS_ANDROID) - - config.always_translate_min_count = 3; - return config; -} diff --git a/chrome/browser/translate/translate_manager.h b/chrome/browser/translate/translate_manager.h index d981ba79bb4d..5911907954b6 100644 --- a/chrome/browser/translate/translate_manager.h +++ b/chrome/browser/translate/translate_manager.h @@ -13,8 +13,6 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" -#include "chrome/browser/ui/translate/translate_bubble_model.h" -#include "components/translate/core/common/translate_errors.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -24,10 +22,8 @@ struct LanguageDetectionDetails; struct PageTranslatedDetails; class PrefService; class Profile; -struct ShortcutConfiguration; class TranslateAcceptLanguages; struct TranslateErrorDetails; -class TranslateInfoBarDelegate; namespace content { class WebContents; @@ -68,13 +64,6 @@ class TranslateManager : public content::NotificationObserver { static std::string GetAutoTargetLanguage(const std::string& original_language, PrefService* prefs); - // Returns true if the new translate bubble is enabled. - static bool IsTranslateBubbleEnabled(); - - // Sets whether of not the infobar UI is used. This method is intented to be - // used only for tests. - static void SetUseInfobar(bool value); - // 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. @@ -159,19 +148,6 @@ class TranslateManager : public content::NotificationObserver { // Notifies to the observers when translate failed. void NotifyTranslateError(const TranslateErrorDetails& details); - // Shows the translate bubble. - void ShowBubble(content::WebContents* web_contents, - TranslateBubbleModel::ViewState view_state, - TranslateErrors::Type error_type); - - // Whether or not the infobar is used. This is intented to be used - // only for testing. - static bool use_infobar_; - - // Returns the different parameters used to decide whether extra shortcuts - // are needed. - static ShortcutConfiguration ShortcutConfig(); - content::NotificationRegistrar notification_registrar_; // Max number of attempts before checking if a page has been reloaded. diff --git a/chrome/browser/translate/translate_manager_browsertest.cc b/chrome/browser/translate/translate_manager_browsertest.cc index ed9aafbe127e..717823f6979d 100644 --- a/chrome/browser/translate/translate_manager_browsertest.cc +++ b/chrome/browser/translate/translate_manager_browsertest.cc @@ -243,7 +243,7 @@ class TranslateManagerBrowserTest : public ChromeRenderViewHostTestHarness, download_manager->ClearTranslateScriptForTesting(); download_manager->SetTranslateScriptExpirationDelay(60 * 60 * 1000); TranslateManager::GetInstance()->set_translate_max_reload_attemps(0); - TranslateManager::SetUseInfobar(true); + TranslateService::SetUseInfobar(true); ChromeRenderViewHostTestHarness::SetUp(); InfoBarService::CreateForWebContents(web_contents()); @@ -1480,7 +1480,7 @@ TEST_F(TranslateManagerBrowserTest, DownloadsAndHistoryNotTranslated) { TEST_F(TranslateManagerBrowserTest, BubbleNormalTranslate) { // Prepare for the bubble - TranslateManager::SetUseInfobar(false); + TranslateService::SetUseInfobar(false); MockTranslateBubbleFactory* factory = new MockTranslateBubbleFactory; scoped_ptr factory_ptr(factory); TranslateBubbleFactory::SetFactory(factory); @@ -1521,7 +1521,7 @@ TEST_F(TranslateManagerBrowserTest, BubbleNormalTranslate) { TEST_F(TranslateManagerBrowserTest, BubbleTranslateScriptNotAvailable) { // Prepare for the bubble - TranslateManager::SetUseInfobar(false); + TranslateService::SetUseInfobar(false); MockTranslateBubbleFactory* factory = new MockTranslateBubbleFactory; scoped_ptr factory_ptr(factory); TranslateBubbleFactory::SetFactory(factory); @@ -1553,7 +1553,7 @@ TEST_F(TranslateManagerBrowserTest, BubbleTranslateScriptNotAvailable) { TEST_F(TranslateManagerBrowserTest, BubbleUnknownLanguage) { // Prepare for the bubble - TranslateManager::SetUseInfobar(false); + TranslateService::SetUseInfobar(false); MockTranslateBubbleFactory* factory = new MockTranslateBubbleFactory; scoped_ptr factory_ptr(factory); TranslateBubbleFactory::SetFactory(factory); diff --git a/chrome/browser/translate/translate_service.cc b/chrome/browser/translate/translate_service.cc index a7625a93c64f..dcff02729df3 100644 --- a/chrome/browser/translate/translate_service.cc +++ b/chrome/browser/translate/translate_service.cc @@ -4,8 +4,10 @@ #include "chrome/browser/translate/translate_service.h" +#include "base/command_line.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/translate/translate_manager.h" +#include "chrome/common/chrome_switches.h" #include "components/translate/core/browser/translate_download_manager.h" namespace { @@ -13,7 +15,7 @@ namespace { TranslateService* g_translate_service = NULL; } -TranslateService::TranslateService() { +TranslateService::TranslateService() : use_infobar_(false) { resource_request_allowed_notifier_.Init(this); } @@ -60,3 +62,24 @@ void TranslateService::OnResourceRequestsAllowed() { language_list->SetResourceRequestsAllowed( resource_request_allowed_notifier_.ResourceRequestsAllowed()); } + +// static +bool TranslateService::IsTranslateBubbleEnabled() { +#if defined(USE_AURA) + Initialize(); + return !g_translate_service->use_infobar_; +#elif defined(OS_MACOSX) + // The bubble UX is experimental on Mac OS X. + return CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableTranslateNewUX); +#else + // The bubble UX is not implemented on the non-Aura platforms. + return false; +#endif +} + +// static +void TranslateService::SetUseInfobar(bool value) { + Initialize(); + g_translate_service->use_infobar_ = value; +} diff --git a/chrome/browser/translate/translate_service.h b/chrome/browser/translate/translate_service.h index b544b5b91d41..818e90477a2d 100644 --- a/chrome/browser/translate/translate_service.h +++ b/chrome/browser/translate/translate_service.h @@ -23,6 +23,13 @@ class TranslateService : public ResourceRequestAllowedNotifier::Observer { // or if prefs::kEnableTranslate is set to false. static void FetchLanguageListFromTranslateServer(PrefService* prefs); + // Returns true if the new translate bubble is enabled. + static bool IsTranslateBubbleEnabled(); + + // Sets whether of not the infobar UI is used. This method is intended to be + // used only for tests. + static void SetUseInfobar(bool value); + private: TranslateService(); ~TranslateService(); @@ -32,6 +39,10 @@ class TranslateService : public ResourceRequestAllowedNotifier::Observer { // Helper class to know if it's allowed to make network resource requests. ResourceRequestAllowedNotifier resource_request_allowed_notifier_; + + // Whether or not the infobar is used. This is intended to be used + // only for testing. + bool use_infobar_; }; #endif // CHROME_BROWSER_TRANSLATE_TRANSLATE_SERVICE_H_ diff --git a/chrome/browser/translate/translate_tab_helper.cc b/chrome/browser/translate/translate_tab_helper.cc index 701a116ba391..fbe08b8c9446 100644 --- a/chrome/browser/translate/translate_tab_helper.cc +++ b/chrome/browser/translate/translate_tab_helper.cc @@ -5,17 +5,79 @@ #include "chrome/browser/translate/translate_tab_helper.h" #include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/translate/translate_infobar_delegate.h" +#include "chrome/browser/translate/translate_service.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/translate/translate_bubble_factory.h" #include "chrome/common/render_messages.h" #include "components/translate/core/browser/page_translated_details.h" #include "components/translate/core/common/language_detection_details.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/web_contents.h" -using content::WebContents; +namespace { + +// Converts from TranslateTabHelper::TranslateStep to +// TranslateBubbleModel::ViewState. +TranslateBubbleModel::ViewState BubbleViewStateFromStep( + TranslateTabHelper::TranslateStep step, + TranslateErrors::Type error_type) { + if (error_type != TranslateErrors::NONE) + return TranslateBubbleModel::VIEW_STATE_ERROR; + + switch (step) { + case TranslateTabHelper::BEFORE_TRANSLATE: + return TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE; + case TranslateTabHelper::TRANSLATING: + return TranslateBubbleModel::VIEW_STATE_TRANSLATING; + case TranslateTabHelper::AFTER_TRANSLATE: + return TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE; + case TranslateTabHelper::TRANSLATE_ERROR: + NOTREACHED() << "error_type should not be NONE"; + return TranslateBubbleModel::VIEW_STATE_ERROR; + } + + // This return statement is here to avoid some compilers to incorrectly + // complain about reaching the end of a non-void function. + NOTREACHED(); + return TranslateBubbleModel::VIEW_STATE_ERROR; +} + +// Converts from TranslateTabHelper::TranslateStep to +// TranslateInfoBarDelegate::Type. +TranslateInfoBarDelegate::Type InfobarTypeFromStep( + TranslateTabHelper::TranslateStep step, + TranslateErrors::Type error_type) { + if (error_type != TranslateErrors::NONE) + return TranslateInfoBarDelegate::TRANSLATION_ERROR; + + switch (step) { + case TranslateTabHelper::BEFORE_TRANSLATE: + return TranslateInfoBarDelegate::BEFORE_TRANSLATE; + case TranslateTabHelper::TRANSLATING: + return TranslateInfoBarDelegate::TRANSLATING; + case TranslateTabHelper::AFTER_TRANSLATE: + return TranslateInfoBarDelegate::AFTER_TRANSLATE; + case TranslateTabHelper::TRANSLATE_ERROR: + NOTREACHED() << "error_type should not be NONE"; + return TranslateInfoBarDelegate::TRANSLATION_ERROR; + } + + // This return statement is here to avoid some compilers to incorrectly + // complain about reaching the end of a non-void function. + NOTREACHED(); + return TranslateInfoBarDelegate::TRANSLATION_ERROR; +} + +} // namespace DEFINE_WEB_CONTENTS_USER_DATA_KEY(TranslateTabHelper); -TranslateTabHelper::TranslateTabHelper(WebContents* web_contents) +TranslateTabHelper::TranslateTabHelper(content::WebContents* web_contents) : content::WebContentsObserver(web_contents), translate_driver_(&web_contents->GetController()) { } @@ -27,6 +89,45 @@ LanguageState& TranslateTabHelper::GetLanguageState() { return translate_driver_.language_state(); } +void TranslateTabHelper::ShowTranslateUI(TranslateTabHelper::TranslateStep step, + content::WebContents* web_contents, + const std::string source_language, + const std::string target_language, + TranslateErrors::Type error_type) { + if (TranslateService::IsTranslateBubbleEnabled()) { + // Bubble UI. + TranslateBubbleModel::ViewState view_state = + BubbleViewStateFromStep(step, error_type); + if (view_state == TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE) { + // TODO: Move this logic out of UI code. + GetLanguageState().SetTranslateEnabled(true); + if (!GetLanguageState().HasLanguageChanged()) + return; + } + ShowBubble(web_contents, view_state, error_type); + return; + } + + // Infobar UI. + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + Profile* original_profile = profile->GetOriginalProfile(); + PrefService* prefs = original_profile->GetPrefs(); + + TranslateInfoBarDelegate::Type infobar_type = + InfobarTypeFromStep(step, error_type); + bool replace_existing = + infobar_type != TranslateInfoBarDelegate::BEFORE_TRANSLATE; + + TranslateInfoBarDelegate::Create(replace_existing, + web_contents, + infobar_type, + source_language, + target_language, + error_type, + prefs); +} + bool TranslateTabHelper::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(TranslateTabHelper, message) @@ -54,7 +155,7 @@ void TranslateTabHelper::OnLanguageDetermined( content::NotificationService::current()->Notify( chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED, - content::Source(web_contents()), + content::Source(web_contents()), content::Details(&details)); } @@ -70,6 +171,47 @@ void TranslateTabHelper::OnPageTranslated(int32 page_id, details.error_type = error_type; content::NotificationService::current()->Notify( chrome::NOTIFICATION_PAGE_TRANSLATED, - content::Source(web_contents()), + content::Source(web_contents()), content::Details(&details)); } + +void TranslateTabHelper::ShowBubble(content::WebContents* web_contents, + TranslateBubbleModel::ViewState view_state, + TranslateErrors::Type error_type) { +// The bubble is implemented only on the desktop platforms. +#if !defined(OS_ANDROID) && !defined(OS_IOS) + Browser* browser = chrome::FindBrowserWithWebContents(web_contents); + + // |browser| might be NULL when testing. In this case, Show(...) should be + // called because the implementation for testing is used. + if (!browser) { + TranslateBubbleFactory::Show(NULL, web_contents, view_state, error_type); + return; + } + + if (web_contents != browser->tab_strip_model()->GetActiveWebContents()) + return; + + // This ShowBubble function is also used for upating the existing bubble. + // However, with the bubble shown, any browser windows are NOT activated + // because the bubble takes the focus from the other widgets including the + // browser windows. So it is checked that |browser| is the last activated + // browser, not is now activated. + if (browser != + chrome::FindLastActiveWithHostDesktopType(browser->host_desktop_type())) { + return; + } + + // During auto-translating, the bubble should not be shown. + if (view_state == TranslateBubbleModel::VIEW_STATE_TRANSLATING || + view_state == TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE) { + if (GetLanguageState().InTranslateNavigation()) + return; + } + + TranslateBubbleFactory::Show( + browser->window(), web_contents, view_state, error_type); +#else + NOTREACHED(); +#endif +} diff --git a/chrome/browser/translate/translate_tab_helper.h b/chrome/browser/translate/translate_tab_helper.h index d4cf7a2c70a9..6348cd2c621b 100644 --- a/chrome/browser/translate/translate_tab_helper.h +++ b/chrome/browser/translate/translate_tab_helper.h @@ -5,11 +5,18 @@ #ifndef CHROME_BROWSER_TRANSLATE_TRANSLATE_TAB_HELPER_H_ #define CHROME_BROWSER_TRANSLATE_TRANSLATE_TAB_HELPER_H_ +#include + +#include "chrome/browser/ui/translate/translate_bubble_model.h" #include "components/translate/content/browser/content_translate_driver.h" #include "components/translate/core/common/translate_errors.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" +namespace content { +class WebContents; +} + struct LanguageDetectionDetails; class TranslateTabHelper @@ -25,6 +32,22 @@ class TranslateTabHelper // WebContents. ContentTranslateDriver& translate_driver() { return translate_driver_; } + // Denotes which state the user is in with respect to translate. + enum TranslateStep { + BEFORE_TRANSLATE, + TRANSLATING, + AFTER_TRANSLATE, + TRANSLATE_ERROR + }; + + // Called when the embedder should present UI to the user corresponding to the + // user's current |step|. + void ShowTranslateUI(TranslateStep step, + content::WebContents* web_contents, + const std::string source_language, + const std::string target_language, + TranslateErrors::Type error_type); + private: explicit TranslateTabHelper(content::WebContents* web_contents); friend class content::WebContentsUserData; @@ -42,6 +65,11 @@ class TranslateTabHelper const std::string& translated_lang, TranslateErrors::Type error_type); + // Shows the translate bubble. + void ShowBubble(content::WebContents* web_contents, + TranslateBubbleModel::ViewState view_state, + TranslateErrors::Type error_type); + ContentTranslateDriver translate_driver_; DISALLOW_COPY_AND_ASSIGN(TranslateTabHelper); diff --git a/chrome/browser/ui/cocoa/infobars/translate_infobar_unittest.mm b/chrome/browser/ui/cocoa/infobars/translate_infobar_unittest.mm index 3cc88c73efeb..47b6ad6fa994 100644 --- a/chrome/browser/ui/cocoa/infobars/translate_infobar_unittest.mm +++ b/chrome/browser/ui/cocoa/infobars/translate_infobar_unittest.mm @@ -39,10 +39,9 @@ class MockTranslateInfoBarDelegate : public TranslateInfoBarDelegate { MockTranslateInfoBarDelegate(content::WebContents* web_contents, TranslateInfoBarDelegate::Type type, TranslateErrors::Type error, - PrefService* prefs, - ShortcutConfiguration config) + PrefService* prefs) : TranslateInfoBarDelegate(web_contents, type, NULL, "en", "es", error, - prefs, config) { + prefs) { } MOCK_METHOD0(Translate, void()); @@ -89,14 +88,11 @@ class TranslationInfoBarTest : public CocoaProfileTest { error = TranslateErrors::NETWORK; Profile* profile = Profile::FromBrowserContext(web_contents_->GetBrowserContext()); - ShortcutConfiguration config; - config.never_translate_min_count = 3; - config.always_translate_min_count = 3; [[infobar_controller_ view] removeFromSuperview]; scoped_ptr delegate( new MockTranslateInfoBarDelegate(web_contents_.get(), type, error, - profile->GetPrefs(), config)); + profile->GetPrefs())); scoped_ptr infobar( TranslateInfoBarDelegate::CreateInfoBar(delegate.Pass())); if (infobar_) diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index 7e0cd928b6ba..56471a8a4497 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc @@ -27,7 +27,7 @@ #include "chrome/browser/search_engines/template_url.h" #include "chrome/browser/search_engines/template_url_service.h" #include "chrome/browser/search_engines/template_url_service_factory.h" -#include "chrome/browser/translate/translate_manager.h" +#include "chrome/browser/translate/translate_service.h" #include "chrome/browser/translate/translate_tab_helper.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" @@ -1476,7 +1476,7 @@ bool LocationBarView::RefreshManagePasswordsIconView() { } void LocationBarView::RefreshTranslateIcon() { - if (!TranslateManager::IsTranslateBubbleEnabled()) + if (!TranslateService::IsTranslateBubbleEnabled()) return; WebContents* web_contents = GetWebContents(); -- 2.11.4.GIT