Commit 5cd64127 authored by droger's avatar droger Committed by Commit bot

Move navigation handling code from TranslateClient to TranslateDriver

This CL moves code from chrome/ (ChromeTranslateClient) to the
translate component (ContentTranslateDriver).

BUG=331509

Review URL: https://codereview.chromium.org/558663003

Cr-Commit-Position: refs/heads/master@{#294157}
parent 96d38dad
......@@ -34,21 +34,14 @@
#include "components/translate/core/browser/translate_manager.h"
#include "components/translate/core/browser/translate_prefs.h"
#include "components/translate/core/common/language_detection_details.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "grit/theme_resources.h"
#include "net/http/http_status_code.h"
#include "url/gurl.h"
namespace {
// The maximum number of attempts we'll do to see if the page has finshed
// loading before giving up the translation
const int kMaxTranslateLoadCheckAttempts = 20;
// TODO(andrewhayden): Make the data file path into a gyp/gn define
// If you change this, also update standalone_cld_data_harness.cc
// accordingly!
......@@ -63,13 +56,12 @@ DEFINE_WEB_CONTENTS_USER_DATA_KEY(ChromeTranslateClient);
ChromeTranslateClient::ChromeTranslateClient(content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
max_reload_check_attempts_(kMaxTranslateLoadCheckAttempts),
translate_driver_(&web_contents->GetController()),
translate_manager_(
new translate::TranslateManager(this, prefs::kAcceptLanguages)),
cld_data_provider_(
translate::CreateBrowserCldDataProviderFor(web_contents)),
weak_pointer_factory_(this) {
translate::CreateBrowserCldDataProviderFor(web_contents)) {
translate_driver_.set_translate_manager(translate_manager_.get());
// Customization: for the standalone data source, we configure the path to
// CLD data immediately on startup.
if (translate::CldDataSource::ShouldUseStandaloneDataFile() &&
......@@ -287,66 +279,6 @@ bool ChromeTranslateClient::OnMessageReceived(const IPC::Message& message) {
return handled;
}
void ChromeTranslateClient::NavigationEntryCommitted(
const content::LoadCommittedDetails& load_details) {
// Check whether this is a reload: When doing a page reload, the
// TranslateLanguageDetermined IPC is not sent so the translation needs to be
// explicitly initiated.
content::NavigationEntry* entry =
web_contents()->GetController().GetActiveEntry();
if (!entry) {
NOTREACHED();
return;
}
// If the navigation happened while offline don't show the translate
// bar since there will be nothing to translate.
if (load_details.http_status_code == 0 ||
load_details.http_status_code == net::HTTP_INTERNAL_SERVER_ERROR) {
return;
}
if (!load_details.is_main_frame &&
GetLanguageState().translation_declined()) {
// Some sites (such as Google map) may trigger sub-frame navigations
// when the user interacts with the page. We don't want to show a new
// infobar if the user already dismissed one in that case.
return;
}
// If not a reload, return.
if (entry->GetTransitionType() != content::PAGE_TRANSITION_RELOAD &&
load_details.type != content::NAVIGATION_TYPE_SAME_PAGE) {
return;
}
if (!GetLanguageState().page_needs_translation())
return;
// Note that we delay it as the ordering of the processing of this callback
// by WebContentsObservers is undefined and might result in the current
// infobars being removed. Since the translation initiation process might add
// an infobar, it must be done after that.
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&ChromeTranslateClient::InitiateTranslation,
weak_pointer_factory_.GetWeakPtr(),
GetLanguageState().original_language(),
0));
}
void ChromeTranslateClient::DidNavigateAnyFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) {
// Let the LanguageState clear its state.
const bool reload =
details.entry->GetTransitionType() == content::PAGE_TRANSITION_RELOAD ||
details.type == content::NAVIGATION_TYPE_SAME_PAGE;
GetLanguageState().DidNavigate(
details.is_in_page, details.is_main_frame, reload);
}
void ChromeTranslateClient::WebContentsDestroyed() {
// Translation process can be interrupted.
// Destroying the TranslateManager now guarantees that it never has to deal
......@@ -354,31 +286,6 @@ void ChromeTranslateClient::WebContentsDestroyed() {
translate_manager_.reset();
}
void ChromeTranslateClient::InitiateTranslation(const std::string& page_lang,
int attempt) {
if (GetLanguageState().translation_pending())
return;
// During a reload we need web content to be available before the
// translate script is executed. Otherwise we will run the translate script on
// an empty DOM which will fail. Therefore we wait a bit to see if the page
// has finished.
if (web_contents()->IsLoading() && attempt < max_reload_check_attempts_) {
int backoff = attempt * kMaxTranslateLoadCheckAttempts;
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&ChromeTranslateClient::InitiateTranslation,
weak_pointer_factory_.GetWeakPtr(),
page_lang,
attempt + 1),
base::TimeDelta::FromMilliseconds(backoff));
return;
}
translate_manager_->InitiateTranslation(
translate::TranslateDownloadManager::GetLanguageCode(page_lang));
}
void ChromeTranslateClient::OnTranslateAssignedSequenceNumber(int page_seq_no) {
translate_manager_->set_current_seq_no(page_seq_no);
}
......
......@@ -8,7 +8,6 @@
#include <string>
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/ui/translate/translate_bubble_model.h"
#include "components/translate/content/browser/browser_cld_data_provider.h"
#include "components/translate/content/browser/content_translate_driver.h"
......@@ -83,11 +82,6 @@ class ChromeTranslateClient
// destroyed.
content::WebContents* GetWebContents();
// Number of attempts before waiting for a page to be fully reloaded.
void set_translate_max_reload_attempts(int attempts) {
max_reload_check_attempts_ = attempts;
}
// TranslateClient implementation.
virtual translate::TranslateDriver* GetTranslateDriver() OVERRIDE;
virtual PrefService* GetPrefs() OVERRIDE;
......@@ -111,17 +105,9 @@ class ChromeTranslateClient
friend class content::WebContentsUserData<ChromeTranslateClient>;
// content::WebContentsObserver implementation.
virtual void NavigationEntryCommitted(
const content::LoadCommittedDetails& load_details) OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
virtual void DidNavigateAnyFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) OVERRIDE;
virtual void WebContentsDestroyed() OVERRIDE;
// Initiates translation once the page is finished loading.
void InitiateTranslation(const std::string& page_lang, int attempt);
// IPC handlers.
void OnTranslateAssignedSequenceNumber(int page_seq_no);
void OnLanguageDetermined(const translate::LanguageDetectionDetails& details,
......@@ -134,17 +120,12 @@ class ChromeTranslateClient
void ShowBubble(translate::TranslateStep step,
translate::TranslateErrors::Type error_type);
// Max number of attempts before checking if a page has been reloaded.
int max_reload_check_attempts_;
translate::ContentTranslateDriver translate_driver_;
scoped_ptr<translate::TranslateManager> translate_manager_;
// Provides CLD data for this process.
scoped_ptr<translate::BrowserCldDataProvider> cld_data_provider_;
base::WeakPtrFactory<ChromeTranslateClient> weak_pointer_factory_;
DISALLOW_COPY_AND_ASSIGN(ChromeTranslateClient);
};
......
......@@ -28,6 +28,7 @@
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "components/infobars/core/infobar.h"
#include "components/translate/content/browser/content_translate_driver.h"
#include "components/translate/content/common/translate_messages.h"
#include "components/translate/core/browser/translate_accept_languages.h"
#include "components/translate/core/browser/translate_download_manager.h"
......@@ -259,7 +260,8 @@ class TranslateManagerRenderViewHostTest
InfoBarService::CreateForWebContents(web_contents());
ChromeTranslateClient::CreateForWebContents(web_contents());
ChromeTranslateClient::FromWebContents(web_contents())
->set_translate_max_reload_attempts(0);
->translate_driver()
.set_translate_max_reload_attempts(0);
notification_registrar_.Add(
this,
......@@ -815,7 +817,8 @@ TEST_F(TranslateManagerRenderViewHostTest, Reload) {
// If we set reload attempts to a high value, we will not see the infobar
// immediately.
ChromeTranslateClient::FromWebContents(web_contents())
->set_translate_max_reload_attempts(100);
->translate_driver()
.set_translate_max_reload_attempts(100);
ReloadAndWait(true);
EXPECT_TRUE(GetTranslateInfoBar() == NULL);
}
......
......@@ -4,28 +4,70 @@
#include "components/translate/content/browser/content_translate_driver.h"
#include "base/bind.h"
#include "base/logging.h"
#include "components/translate/content/common/translate_messages.h"
#include "components/translate/core/browser/translate_download_manager.h"
#include "components/translate/core/browser/translate_manager.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/page_navigator.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/referrer.h"
#include "net/http/http_status_code.h"
#include "url/gurl.h"
namespace {
// The maximum number of attempts we'll do to see if the page has finshed
// loading before giving up the translation
const int kMaxTranslateLoadCheckAttempts = 20;
} // namespace
namespace translate {
ContentTranslateDriver::ContentTranslateDriver(
content::NavigationController* nav_controller)
: navigation_controller_(nav_controller),
observer_(NULL) {
: content::WebContentsObserver(nav_controller->GetWebContents()),
navigation_controller_(nav_controller),
translate_manager_(NULL),
observer_(NULL),
max_reload_check_attempts_(kMaxTranslateLoadCheckAttempts),
weak_pointer_factory_(this) {
DCHECK(navigation_controller_);
}
ContentTranslateDriver::~ContentTranslateDriver() {}
void ContentTranslateDriver::InitiateTranslation(const std::string& page_lang,
int attempt) {
if (translate_manager_->GetLanguageState().translation_pending())
return;
// During a reload we need web content to be available before the
// translate script is executed. Otherwise we will run the translate script on
// an empty DOM which will fail. Therefore we wait a bit to see if the page
// has finished.
if (web_contents()->IsLoading() && attempt < max_reload_check_attempts_) {
int backoff = attempt * kMaxTranslateLoadCheckAttempts;
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&ContentTranslateDriver::InitiateTranslation,
weak_pointer_factory_.GetWeakPtr(),
page_lang,
attempt + 1),
base::TimeDelta::FromMilliseconds(backoff));
return;
}
translate_manager_->InitiateTranslation(
translate::TranslateDownloadManager::GetLanguageCode(page_lang));
}
// TranslateDriver methods
bool ContentTranslateDriver::IsLinkNavigation() {
......@@ -108,4 +150,66 @@ void ContentTranslateDriver::OpenUrlInNewTab(const GURL& url) {
navigation_controller_->GetWebContents()->OpenURL(params);
}
// content::WebContentsObserver methods
void ContentTranslateDriver::NavigationEntryCommitted(
const content::LoadCommittedDetails& load_details) {
// Check whether this is a reload: When doing a page reload, the
// TranslateLanguageDetermined IPC is not sent so the translation needs to be
// explicitly initiated.
content::NavigationEntry* entry =
web_contents()->GetController().GetActiveEntry();
if (!entry) {
NOTREACHED();
return;
}
// If the navigation happened while offline don't show the translate
// bar since there will be nothing to translate.
if (load_details.http_status_code == 0 ||
load_details.http_status_code == net::HTTP_INTERNAL_SERVER_ERROR) {
return;
}
if (!load_details.is_main_frame &&
translate_manager_->GetLanguageState().translation_declined()) {
// Some sites (such as Google map) may trigger sub-frame navigations
// when the user interacts with the page. We don't want to show a new
// infobar if the user already dismissed one in that case.
return;
}
// If not a reload, return.
if (entry->GetTransitionType() != content::PAGE_TRANSITION_RELOAD &&
load_details.type != content::NAVIGATION_TYPE_SAME_PAGE) {
return;
}
if (!translate_manager_->GetLanguageState().page_needs_translation())
return;
// Note that we delay it as the ordering of the processing of this callback
// by WebContentsObservers is undefined and might result in the current
// infobars being removed. Since the translation initiation process might add
// an infobar, it must be done after that.
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&ContentTranslateDriver::InitiateTranslation,
weak_pointer_factory_.GetWeakPtr(),
translate_manager_->GetLanguageState().original_language(),
0));
}
void ContentTranslateDriver::DidNavigateAnyFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) {
// Let the LanguageState clear its state.
const bool reload =
details.entry->GetTransitionType() == content::PAGE_TRANSITION_RELOAD ||
details.type == content::NAVIGATION_TYPE_SAME_PAGE;
translate_manager_->GetLanguageState().DidNavigate(
details.is_in_page, details.is_main_frame, reload);
}
} // namespace translate
......@@ -6,7 +6,9 @@
#define COMPONENTS_TRANSLATE_CONTENT_BROWSER_CONTENT_TRANSLATE_DRIVER_H_
#include "base/basictypes.h"
#include "base/memory/weak_ptr.h"
#include "components/translate/core/browser/translate_driver.h"
#include "content/public/browser/web_contents_observer.h"
namespace content {
class NavigationController;
......@@ -15,8 +17,11 @@ class WebContents;
namespace translate {
class TranslateManager;
// Content implementation of TranslateDriver.
class ContentTranslateDriver : public TranslateDriver {
class ContentTranslateDriver : public TranslateDriver,
public content::WebContentsObserver {
public:
// The observer for the ContentTranslateDriver.
......@@ -38,6 +43,19 @@ class ContentTranslateDriver : public TranslateDriver {
// Sets the Observer. Calling this method is optional.
void set_observer(Observer* observer) { observer_ = observer; }
// Number of attempts before waiting for a page to be fully reloaded.
void set_translate_max_reload_attempts(int attempts) {
max_reload_check_attempts_ = attempts;
}
// Sets the TranslateManager associated with this driver.
void set_translate_manager(TranslateManager* manager) {
translate_manager_ = manager;
}
// Initiates translation once the page is finished loading.
void InitiateTranslation(const std::string& page_lang, int attempt);
// TranslateDriver methods.
virtual void OnIsPageTranslatedChanged() OVERRIDE;
virtual void OnTranslateEnabledChanged() OVERRIDE;
......@@ -55,12 +73,26 @@ class ContentTranslateDriver : public TranslateDriver {
virtual bool HasCurrentPage() OVERRIDE;
virtual void OpenUrlInNewTab(const GURL& url) OVERRIDE;
// content::WebContentsObserver implementation.
virtual void NavigationEntryCommitted(
const content::LoadCommittedDetails& load_details) OVERRIDE;
virtual void DidNavigateAnyFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) OVERRIDE;
private:
// The navigation controller of the tab we are associated with.
content::NavigationController* navigation_controller_;
TranslateManager* translate_manager_;
Observer* observer_;
// Max number of attempts before checking if a page has been reloaded.
int max_reload_check_attempts_;
base::WeakPtrFactory<ContentTranslateDriver> weak_pointer_factory_;
DISALLOW_COPY_AND_ASSIGN(ContentTranslateDriver);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment