Commit a6f9dfdb authored by Michael Martis's avatar Michael Martis Committed by Commit Bot

Moved language detection dispatch into the language component on iOS.

This comprises:
  - Attaching an iOS language detection client (similar to the
    existing Content-based client) to each web state
  - Updating the language detection controller (which does the actual
    CLD) to notify the language detection client rather than translate
    code, and to use core datatypes (rather than iOS-specific ones)
  - Updating the translate driver to receive language info via a
    callback from the language detection client
  - Updating unit and integration tests to account for these changes

Bug: 755856
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: I7544863835d0d507a3e1453973f55c7fc918ba83
Reviewed-on: https://chromium-review.googlesource.com/740421
Commit-Queue: Michael Martis <martis@chromium.org>
Reviewed-by: default avatarRenjie Liu <renjieliu@chromium.org>
Reviewed-by: default avatarDavid Roger <droger@chromium.org>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#513070}
parent 6f148d5c
# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
source_set("browser") {
configs += [ "//build/config/compiler:enable_arc" ]
sources = [
"ios_language_detection_tab_helper.h",
"ios_language_detection_tab_helper.mm",
]
deps = [
"//base",
"//components/language/core/browser",
"//components/translate/core/common",
"//ios/web",
"//net",
]
}
include_rules = [
"+components/translate/core/common",
]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_LANUGUAGE_IOS_BROWSER_IOS_LANGUAGE_DETECTION_TAB_HELPER_H_
#define COMPONENTS_LANUGUAGE_IOS_BROWSER_IOS_LANGUAGE_DETECTION_TAB_HELPER_H_
#include "base/callback.h"
#include "base/macros.h"
#include "ios/web/public/web_state/web_state_user_data.h"
namespace translate {
struct LanguageDetectionDetails;
} // namespace translate
namespace language {
class UrlLanguageHistogram;
// Dispatches language detection messages to language and translate components.
class IOSLanguageDetectionTabHelper
: public web::WebStateUserData<IOSLanguageDetectionTabHelper> {
public:
using Callback =
base::RepeatingCallback<void(const translate::LanguageDetectionDetails&)>;
~IOSLanguageDetectionTabHelper() override;
// Attach a new helper to the given WebState. We cannot use the implementation
// from WebStateUserData as we are injecting the histogram and translate
// callback differently on iOS and iOS WebView.
static void CreateForWebState(web::WebState* web_state,
const Callback& translate_callback,
UrlLanguageHistogram* url_language_histogram);
// Called on page language detection.
void OnLanguageDetermined(const translate::LanguageDetectionDetails& details);
// Add an extra listener for language detection. May only be used in tests.
void SetExtraCallbackForTesting(const Callback& callback);
private:
IOSLanguageDetectionTabHelper(
const Callback& translate_callback,
UrlLanguageHistogram* const url_language_histogram);
friend class web::WebStateUserData<IOSLanguageDetectionTabHelper>;
const Callback translate_callback_;
UrlLanguageHistogram* const url_language_histogram_;
Callback extra_callback_for_testing_;
DISALLOW_COPY_AND_ASSIGN(IOSLanguageDetectionTabHelper);
};
} // namespace language
#endif // COMPONENTS_LANUGUAGE_IOS_BROWSER_IOS_LANGUAGE_DETECTION_TAB_HELPER_H_
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/language/ios/browser/ios_language_detection_tab_helper.h"
#include "components/language/core/browser/url_language_histogram.h"
#include "components/translate/core/common/language_detection_details.h"
DEFINE_WEB_STATE_USER_DATA_KEY(language::IOSLanguageDetectionTabHelper);
namespace language {
IOSLanguageDetectionTabHelper::IOSLanguageDetectionTabHelper(
const Callback& translate_callback,
UrlLanguageHistogram* const url_language_histogram)
: translate_callback_(translate_callback),
url_language_histogram_(url_language_histogram) {}
IOSLanguageDetectionTabHelper::~IOSLanguageDetectionTabHelper() = default;
// static
void IOSLanguageDetectionTabHelper::CreateForWebState(
web::WebState* web_state,
const Callback& translate_callback,
UrlLanguageHistogram* const url_language_histogram) {
DCHECK(web_state);
if (!FromWebState(web_state)) {
web_state->SetUserData(UserDataKey(),
base::WrapUnique(new IOSLanguageDetectionTabHelper(
translate_callback, url_language_histogram)));
}
}
void IOSLanguageDetectionTabHelper::OnLanguageDetermined(
const translate::LanguageDetectionDetails& details) {
// Update language histogram.
if (url_language_histogram_ && details.is_cld_reliable) {
url_language_histogram_->OnPageVisited(details.cld_language);
}
// Update translate.
translate_callback_.Run(details);
// Optionally update testing callback.
if (extra_callback_for_testing_) {
extra_callback_for_testing_.Run(details);
}
}
void IOSLanguageDetectionTabHelper::SetExtraCallbackForTesting(
const Callback& callback) {
extra_callback_for_testing_ = callback;
}
} // namespace language
......@@ -24,7 +24,7 @@ source_set("browser") {
deps = [
":injected_js",
"//base",
"//components/language/core/browser",
"//components/language/ios/browser",
"//components/prefs",
"//components/translate/core/browser",
"//components/translate/core/common",
......@@ -56,9 +56,11 @@ source_set("unit_tests") {
deps = [
":browser",
"//base",
"//components/language/ios/browser",
"//components/prefs:test_support",
"//components/resources",
"//components/translate/core/browser",
"//components/translate/core/common",
"//ios/web/public/test",
"//ios/web/public/test/fakes",
"//net:net",
......
......@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/language/ios/browser/ios_language_detection_tab_helper.h"
#include "components/translate/core/browser/translate_driver.h"
#include "components/translate/ios/browser/language_detection_controller.h"
#include "components/translate/ios/browser/translate_controller.h"
......@@ -17,10 +18,6 @@
@class CRWJSInjectionReceiver;
namespace language {
class UrlLanguageHistogram;
}
namespace web {
class NavigationManager;
class WebState;
......@@ -37,8 +34,7 @@ class IOSTranslateDriver : public TranslateDriver,
public:
IOSTranslateDriver(web::WebState* web_state,
web::NavigationManager* navigation_manager,
TranslateManager* translate_manager,
language::UrlLanguageHistogram* language_histogram);
TranslateManager* translate_manager);
~IOSTranslateDriver() override;
LanguageDetectionController* language_detection_controller() {
......@@ -49,6 +45,10 @@ class IOSTranslateDriver : public TranslateDriver,
return translate_controller_.get();
}
// Creates a callback to be used when language detection occurs.
language::IOSLanguageDetectionTabHelper::Callback
CreateLanguageDetectionCallback();
// web::WebStateObserver methods.
void NavigationItemCommitted(
web::WebState* web_state,
......@@ -89,9 +89,8 @@ class IOSTranslateDriver : public TranslateDriver,
// being destroyed.
bool IsPageValid(int page_seq_no) const;
// Callback for LanguageDetectionController.
void OnLanguageDetermined(
const LanguageDetectionController::DetectionDetails& details);
// Used to kick off translation process.
void OnLanguageDetermined(const LanguageDetectionDetails& details);
// TranslateController::Observer methods.
void OnTranslateScriptReady(bool success,
......@@ -104,14 +103,9 @@ class IOSTranslateDriver : public TranslateDriver,
// The navigation manager of the tab we are associated with.
web::NavigationManager* navigation_manager_;
// Model to be notified about detected language of every page visited.
language::UrlLanguageHistogram* language_histogram_;
base::WeakPtr<TranslateManager> translate_manager_;
std::unique_ptr<TranslateController> translate_controller_;
std::unique_ptr<LanguageDetectionController> language_detection_controller_;
std::unique_ptr<LanguageDetectionController::CallbackList::Subscription>
language_detection_callback_subscription_;
// An ever-increasing sequence number of the current page, used to match up
// translation requests with responses.
......
......@@ -9,7 +9,6 @@
#include "base/strings/sys_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "components/language/core/browser/url_language_histogram.h"
#include "components/translate/core/browser/translate_client.h"
#include "components/translate/core/browser/translate_manager.h"
#include "components/translate/core/common/language_detection_details.h"
......@@ -51,11 +50,9 @@ const char kAutoDetectionLanguage[] = "auto";
IOSTranslateDriver::IOSTranslateDriver(
web::WebState* web_state,
web::NavigationManager* navigation_manager,
TranslateManager* translate_manager,
language::UrlLanguageHistogram* language_histogram)
TranslateManager* translate_manager)
: web::WebStateObserver(web_state),
navigation_manager_(navigation_manager),
language_histogram_(language_histogram),
translate_manager_(translate_manager->GetWeakPtr()),
page_seq_no_(0),
pending_page_seq_no_(0),
......@@ -74,10 +71,7 @@ IOSTranslateDriver::IOSTranslateDriver(
language_detection_controller_.reset(new LanguageDetectionController(
web_state, language_detection_manager,
translate_manager_->translate_client()->GetPrefs()));
language_detection_callback_subscription_ =
language_detection_controller_->RegisterLanguageDetectionCallback(
base::Bind(&IOSTranslateDriver::OnLanguageDetermined,
base::Unretained(this)));
// Create the translate controller.
JsTranslateManager* js_translate_manager = static_cast<JsTranslateManager*>(
[receiver instanceOfClass:[JsTranslateManager class]]);
......@@ -89,24 +83,20 @@ IOSTranslateDriver::IOSTranslateDriver(
IOSTranslateDriver::~IOSTranslateDriver() {
}
language::IOSLanguageDetectionTabHelper::Callback
IOSTranslateDriver::CreateLanguageDetectionCallback() {
return base::Bind(&IOSTranslateDriver::OnLanguageDetermined,
weak_method_factory_.GetWeakPtr());
}
void IOSTranslateDriver::OnLanguageDetermined(
const LanguageDetectionController::DetectionDetails& details) {
const translate::LanguageDetectionDetails& details) {
if (!translate_manager_)
return;
translate_manager_->GetLanguageState().LanguageDetermined(
details.adopted_language, true);
// Update language histogram.
if (language_histogram_ && details.is_cld_reliable) {
language_histogram_->OnPageVisited(details.cld_language);
}
translate::LanguageDetectionDetails detection_details;
detection_details.cld_language = details.cld_language;
detection_details.is_cld_reliable = details.is_cld_reliable;
detection_details.adopted_language = details.adopted_language;
translate_manager_->translate_client()->RecordLanguageDetectionEvent(
detection_details);
translate_manager_->translate_client()->RecordLanguageDetectionEvent(details);
if (web_state())
translate_manager_->InitiateTranslation(details.adopted_language);
......
......@@ -37,44 +37,11 @@ namespace translate {
class LanguageDetectionController : public web::WebStateObserver {
public:
// Language detection details, passed to language detection callbacks.
// TODO(crbug.com/715447): Investigate if we can use the existing
// detection_details under
// components/translate/core/common/language_detection_details.h.
struct DetectionDetails {
DetectionDetails();
DetectionDetails(const DetectionDetails& other);
~DetectionDetails();
// The language detected by the content (Content-Language).
std::string content_language;
// The language written in the lang attribute of the html element.
std::string html_root_language;
// The adopted language.
std::string adopted_language;
// The language detected by CLD.
std::string cld_language;
// Whether the CLD detection is reliable or not.
bool is_cld_reliable;
};
LanguageDetectionController(web::WebState* web_state,
JsLanguageDetectionManager* manager,
PrefService* prefs);
~LanguageDetectionController() override;
// Callback types for language detection events.
typedef base::Callback<void(const DetectionDetails&)> Callback;
typedef base::CallbackList<void(const DetectionDetails&)> CallbackList;
// Registers a callback for language detection events.
std::unique_ptr<CallbackList::Subscription> RegisterLanguageDetectionCallback(
const Callback& callback);
private:
FRIEND_TEST_ALL_PREFIXES(LanguageDetectionControllerTest, OnTextCaptured);
FRIEND_TEST_ALL_PREFIXES(LanguageDetectionControllerTest,
......@@ -93,6 +60,7 @@ class LanguageDetectionController : public web::WebStateObserver {
// JsLanguageDetectionManager.
void OnTextRetrieved(const std::string& http_content_language,
const std::string& html_lang,
const GURL& url,
const base::string16& text);
// Extracts "content-language" header into content_language_header_ variable.
......@@ -106,7 +74,6 @@ class LanguageDetectionController : public web::WebStateObserver {
web::NavigationContext* navigation_context) override;
void WebStateDestroyed(web::WebState* web_state) override;
CallbackList language_detection_callbacks_;
JsLanguageDetectionManager* js_manager_;
BooleanPrefMember translate_enabled_;
std::string content_language_header_;
......
......@@ -10,8 +10,10 @@
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "components/language/ios/browser/ios_language_detection_tab_helper.h"
#include "components/prefs/pref_member.h"
#include "components/translate/core/browser/translate_pref_names.h"
#include "components/translate/core/common/language_detection_details.h"
#include "components/translate/core/language_detection/language_detection_util.h"
#import "components/translate/ios/browser/js_language_detection_manager.h"
#include "components/translate/ios/browser/string_clipping_util.h"
......@@ -53,20 +55,6 @@ LanguageDetectionController::LanguageDetectionController(
LanguageDetectionController::~LanguageDetectionController() {
}
LanguageDetectionController::DetectionDetails::DetectionDetails()
: is_cld_reliable(false) {}
LanguageDetectionController::DetectionDetails::DetectionDetails(
const DetectionDetails& other) = default;
LanguageDetectionController::DetectionDetails::~DetectionDetails() = default;
std::unique_ptr<LanguageDetectionController::CallbackList::Subscription>
LanguageDetectionController::RegisterLanguageDetectionCallback(
const Callback& callback) {
return language_detection_callbacks_.Add(callback);
}
void LanguageDetectionController::StartLanguageDetection() {
if (!translate_enabled_.GetValue())
return; // Translate disabled in preferences.
......@@ -116,13 +104,14 @@ bool LanguageDetectionController::OnTextCaptured(
[js_manager_ retrieveBufferedTextContent:
base::Bind(&LanguageDetectionController::OnTextRetrieved,
weak_method_factory_.GetWeakPtr(),
http_content_language, html_lang)];
http_content_language, html_lang, url)];
return true;
}
void LanguageDetectionController::OnTextRetrieved(
const std::string& http_content_language,
const std::string& html_lang,
const GURL& url,
const base::string16& text_content) {
std::string cld_language;
bool is_cld_reliable;
......@@ -134,13 +123,20 @@ void LanguageDetectionController::OnTextRetrieved(
if (language.empty())
return; // No language detected.
DetectionDetails details;
// Avoid an unnecessary copy of the full text content (which can be
// ~64kB) until we need it on iOS (e.g. for the translate internals
// page).
LanguageDetectionDetails details;
details.time = base::Time::Now();
details.url = url;
details.content_language = http_content_language;
details.html_root_language = html_lang;
details.adopted_language = language;
details.cld_language = cld_language;
details.is_cld_reliable = is_cld_reliable;
language_detection_callbacks_.Notify(details);
details.html_root_language = html_lang;
details.adopted_language = language;
language::IOSLanguageDetectionTabHelper::FromWebState(web_state())
->OnLanguageDetermined(details);
}
void LanguageDetectionController::ExtractContentLanguageHeader(
......
......@@ -4,12 +4,15 @@
#import "components/translate/ios/browser/language_detection_controller.h"
#include "base/callback.h"
#include "base/mac/bind_objc_block.h"
#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/language/ios/browser/ios_language_detection_tab_helper.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "components/translate/core/browser/translate_pref_names.h"
#include "components/translate/core/common/language_detection_details.h"
#import "components/translate/ios/browser/js_language_detection_manager.h"
#import "ios/web/public/test/fakes/fake_navigation_context.h"
#import "ios/web/public/test/fakes/test_web_state.h"
......@@ -37,22 +40,34 @@ namespace {
class LanguageDetectionControllerTest : public PlatformTest {
protected:
LanguageDetectionControllerTest() {
LanguageDetectionControllerTest() : details_(nullptr) {
prefs_.registry()->RegisterBooleanPref(prefs::kEnableTranslate, true);
language::IOSLanguageDetectionTabHelper::CreateForWebState(
&web_state_,
base::Bind(&LanguageDetectionControllerTest::OnLanguageDetermined,
base::Unretained(this)),
nullptr);
MockJsLanguageDetectionManager* js_manager =
[[MockJsLanguageDetectionManager alloc] init];
controller_ = base::MakeUnique<LanguageDetectionController>(
&web_state_, js_manager, &prefs_);
}
LanguageDetectionController* controller() { return controller_.get(); }
web::TestWebState& web_state() { return web_state_; }
LanguageDetectionController* controller() { return controller_.get(); }
LanguageDetectionDetails* details() { return details_.get(); }
private:
TestingPrefServiceSimple prefs_;
web::TestWebState web_state_;
std::unique_ptr<LanguageDetectionController> controller_;
std::unique_ptr<LanguageDetectionDetails> details_;
void OnLanguageDetermined(const LanguageDetectionDetails& details) {
details_ = base::MakeUnique<LanguageDetectionDetails>(details);
}
};
} // namespace
......@@ -64,17 +79,6 @@ TEST_F(LanguageDetectionControllerTest, OnTextCaptured) {
const std::string kContentLanguage("fr");
const std::string kUndefined("und");
__block bool block_was_called = false;
auto subscription =
controller()->RegisterLanguageDetectionCallback(base::BindBlockArc(
^(const LanguageDetectionController::DetectionDetails& details) {
block_was_called = true;
EXPECT_EQ(kRootLanguage, details.html_root_language);
EXPECT_EQ(kContentLanguage, details.content_language);
EXPECT_FALSE(details.is_cld_reliable);
EXPECT_EQ(kUndefined, details.cld_language);
}));
base::DictionaryValue command;
command.SetString("command", "languageDetection.textCaptured");
command.SetBoolean("translationAllowed", true);
......@@ -83,7 +87,12 @@ TEST_F(LanguageDetectionControllerTest, OnTextCaptured) {
command.SetString("httpContentLanguage", kContentLanguage);
controller()->OnTextCaptured(command, GURL("http://google.com"), false);
EXPECT_TRUE(block_was_called);
const LanguageDetectionDetails* const details = this->details();
EXPECT_NE(nullptr, details);
EXPECT_EQ(kRootLanguage, details->html_root_language);
EXPECT_EQ(kContentLanguage, details->content_language);
EXPECT_FALSE(details->is_cld_reliable);
EXPECT_EQ(kUndefined, details->cld_language);
}
// Tests that Content-Language response header is used if httpContentLanguage
......@@ -97,14 +106,6 @@ TEST_F(LanguageDetectionControllerTest, MissingHttpContentLanguage) {
context.SetResponseHeaders(headers);
web_state().OnNavigationFinished(&context);
__block bool block_was_called = false;
auto subscription =
controller()->RegisterLanguageDetectionCallback(base::BindBlockArc(
^(const LanguageDetectionController::DetectionDetails& details) {
block_was_called = true;
EXPECT_EQ("fr", details.content_language);
}));
base::DictionaryValue command;
command.SetString("command", "languageDetection.textCaptured");
command.SetBoolean("translationAllowed", true);
......@@ -113,7 +114,9 @@ TEST_F(LanguageDetectionControllerTest, MissingHttpContentLanguage) {
command.SetString("httpContentLanguage", "");
controller()->OnTextCaptured(command, GURL("http://google.com"), false);
EXPECT_TRUE(block_was_called);
const LanguageDetectionDetails* const details = this->details();
EXPECT_NE(nullptr, details);
EXPECT_EQ("fr", details->content_language);
}
} // namespace translate
......@@ -72,6 +72,7 @@ source_set("tabs_internal") {
"//components/history/ios/browser",
"//components/infobars/core",
"//components/keyed_service/core",
"//components/language/ios/browser",
"//components/metrics_services_manager",
"//components/navigation_metrics",
"//components/prefs",
......@@ -93,6 +94,7 @@ source_set("tabs_internal") {
"//ios/chrome/browser/history",
"//ios/chrome/browser/history:tab_helper",
"//ios/chrome/browser/infobars",
"//ios/chrome/browser/language",
"//ios/chrome/browser/metrics",
"//ios/chrome/browser/metrics:metrics_internal",
"//ios/chrome/browser/passwords",
......
......@@ -12,6 +12,7 @@
#include "components/history/core/browser/top_sites.h"
#import "components/history/ios/browser/web_state_top_sites_observer.h"
#include "components/keyed_service/core/service_access_type.h"
#import "components/language/ios/browser/ios_language_detection_tab_helper.h"
#import "ios/chrome/browser/autofill/autofill_tab_helper.h"
#import "ios/chrome/browser/autofill/form_input_accessory_view_tab_helper.h"
#import "ios/chrome/browser/autofill/form_suggestion_tab_helper.h"
......@@ -22,6 +23,7 @@
#include "ios/chrome/browser/history/history_tab_helper.h"
#include "ios/chrome/browser/history/top_sites_factory.h"
#import "ios/chrome/browser/infobars/infobar_manager_impl.h"
#import "ios/chrome/browser/language/url_language_histogram_factory.h"
#import "ios/chrome/browser/passwords/password_tab_helper.h"
#import "ios/chrome/browser/passwords/passwords_ui_delegate_impl.h"
#include "ios/chrome/browser/reading_list/reading_list_model_factory.h"
......@@ -80,7 +82,15 @@ void AttachTabHelpers(web::WebState* web_state) {
ReadingListModelFactory::GetForBrowserState(browser_state);
ReadingListWebStateObserver::FromWebState(web_state, model);
// The language detection helper accepts a callback from the translate
// client, so must be created after it.
ChromeIOSTranslateClient::CreateForWebState(web_state);
language::IOSLanguageDetectionTabHelper::CreateForWebState(
web_state,
ChromeIOSTranslateClient::FromWebState(web_state)
->GetTranslateDriver()
->CreateLanguageDetectionCallback(),
UrlLanguageHistogramFactory::GetForBrowserState(browser_state));
ios::ChromeBrowserState* original_browser_state =
browser_state->GetOriginalChromeBrowserState();
......
......@@ -95,6 +95,7 @@ source_set("external_url_eg_tests") {
deps = [
":translate",
"//base",
"//components/language/ios/browser",
"//components/strings",
"//components/translate/core/browser",
"//components/translate/core/common",
......
......@@ -49,7 +49,7 @@ class ChromeIOSTranslateClient
translate::TranslateManager* GetTranslateManager();
// TranslateClient implementation.
translate::TranslateDriver* GetTranslateDriver() override;
translate::IOSTranslateDriver* GetTranslateDriver() override;
PrefService* GetPrefs() override;
std::unique_ptr<translate::TranslatePrefs> GetTranslatePrefs() override;
translate::TranslateAcceptLanguages* GetTranslateAcceptLanguages() override;
......
......@@ -29,7 +29,6 @@
#include "ios/chrome/browser/infobars/infobar_controller.h"
#include "ios/chrome/browser/infobars/infobar_manager_impl.h"
#include "ios/chrome/browser/language/language_model_factory.h"
#include "ios/chrome/browser/language/url_language_histogram_factory.h"
#include "ios/chrome/browser/pref_names.h"
#import "ios/chrome/browser/sync/ios_user_event_service_factory.h"
#import "ios/chrome/browser/translate/after_translate_infobar_controller.h"
......@@ -65,10 +64,7 @@ ChromeIOSTranslateClient::ChromeIOSTranslateClient(web::WebState* web_state)
web_state->GetBrowserState())))),
translate_driver_(web_state,
web_state->GetNavigationManager(),
translate_manager_.get(),
UrlLanguageHistogramFactory::GetForBrowserState(
ios::ChromeBrowserState::FromBrowserState(
web_state->GetBrowserState()))) {}
translate_manager_.get()) {}
ChromeIOSTranslateClient::~ChromeIOSTranslateClient() {
}
......@@ -163,7 +159,7 @@ void ChromeIOSTranslateClient::ShowTranslateUI(
target_language, error_type, triggered_from_menu);
}
translate::TranslateDriver* ChromeIOSTranslateClient::GetTranslateDriver() {
translate::IOSTranslateDriver* ChromeIOSTranslateClient::GetTranslateDriver() {
return &translate_driver_;
}
......
......@@ -10,10 +10,12 @@
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "components/language/ios/browser/ios_language_detection_tab_helper.h"
#include "components/strings/grit/components_strings.h"
#include "components/translate/core/browser/translate_download_manager.h"
#include "components/translate/core/browser/translate_manager.h"
#include "components/translate/core/browser/translate_pref_names.h"
#include "components/translate/core/common/language_detection_details.h"
#include "components/translate/core/common/translate_constants.h"
#include "components/translate/core/common/translate_switches.h"
#include "components/translate/ios/browser/ios_translate_driver.h"
......@@ -301,9 +303,7 @@ using translate::LanguageDetectionController;
// Tests for translate.
@interface TranslateTestCase : ChromeTestCase {
std::unique_ptr<LanguageDetectionController::CallbackList::Subscription>
_subscription;
std::unique_ptr<LanguageDetectionController::DetectionDetails>
std::unique_ptr<translate::LanguageDetectionDetails>
_language_detection_details;
}
@end
......@@ -312,26 +312,22 @@ using translate::LanguageDetectionController;
- (void)setUp {
[super setUp];
// Creates a LanguageDetectionController::Callback. The callback is deleted in
// tearDown.
LanguageDetectionController::Callback copyDetailsCallback =
base::BindBlockArc(^(
const LanguageDetectionController::DetectionDetails& details) {
_language_detection_details.reset(
new LanguageDetectionController::DetectionDetails(details));
language::IOSLanguageDetectionTabHelper::Callback copyDetailsCallback =
base::BindBlockArc(^(const translate::LanguageDetectionDetails& details) {
_language_detection_details =
base::MakeUnique<translate::LanguageDetectionDetails>(details);
});
ChromeIOSTranslateClient* client = ChromeIOSTranslateClient::FromWebState(
chrome_test_util::GetCurrentWebState());
translate::IOSTranslateDriver* driver =
static_cast<translate::IOSTranslateDriver*>(client->GetTranslateDriver());
_subscription = driver->language_detection_controller()
->RegisterLanguageDetectionCallback(copyDetailsCallback);
language::IOSLanguageDetectionTabHelper::FromWebState(
chrome_test_util::GetCurrentWebState())
->SetExtraCallbackForTesting(copyDetailsCallback);
}
- (void)tearDown {
DCHECK(_subscription);
_subscription.reset();
language::IOSLanguageDetectionTabHelper::FromWebState(
chrome_test_util::GetCurrentWebState())
->SetExtraCallbackForTesting(
language::IOSLanguageDetectionTabHelper::Callback());
_language_detection_details.reset();
// TODO(crbug.com/642892): Investigate moving into test-specific teardown.
// Re-enable translate.
......@@ -360,7 +356,7 @@ using translate::LanguageDetectionController;
GetFrenchPageHtml(kHtmlAttributeWithDeLang, kMetaItContentLanguage);
web::test::SetUpSimpleHttpServer(responses);
LanguageDetectionController::DetectionDetails expectedLanguageDetails;
translate::LanguageDetectionDetails expectedLanguageDetails;
expectedLanguageDetails.content_language = "it";
expectedLanguageDetails.html_root_language = "de";
expectedLanguageDetails.adopted_language = translate::kUnknownLanguageCode;
......@@ -381,7 +377,7 @@ using translate::LanguageDetectionController;
[ChromeEarlGrey loadURL:URL];
// Check for no language detected.
LanguageDetectionController::DetectionDetails expectedLanguageDetails;
translate::LanguageDetectionDetails expectedLanguageDetails;
expectedLanguageDetails.adopted_language = translate::kUnknownLanguageCode;
[self assertLanguageDetails:expectedLanguageDetails];
}
......@@ -428,7 +424,7 @@ using translate::LanguageDetectionController;
[ChromeEarlGrey loadURL:URL];
// Check for no language detected.
LanguageDetectionController::DetectionDetails expectedLanguageDetails;
translate::LanguageDetectionDetails expectedLanguageDetails;
expectedLanguageDetails.adopted_language = "und";
[self assertLanguageDetails:expectedLanguageDetails];
// Change the text of the page.
......@@ -467,7 +463,7 @@ using translate::LanguageDetectionController;
[ChromeEarlGrey loadURL:URL];
// Check that language has been detected.
LanguageDetectionController::DetectionDetails expectedLanguageDetails;
translate::LanguageDetectionDetails expectedLanguageDetails;
expectedLanguageDetails.adopted_language = "fr";
[self assertLanguageDetails:expectedLanguageDetails];
// Trigger the hash change.
......@@ -482,7 +478,7 @@ using translate::LanguageDetectionController;
// Start the HTTP server.
std::unique_ptr<web::DataResponseProvider> provider(new TestResponseProvider);
web::test::SetUpHttpServer(std::move(provider));
LanguageDetectionController::DetectionDetails expectedLanguageDetails;
translate::LanguageDetectionDetails expectedLanguageDetails;
// The HTTP header is detected.
GURL URL = web::test::HttpServer::MakeUrl(std::string("http://") +
......@@ -522,7 +518,7 @@ using translate::LanguageDetectionController;
// Start the HTTP server.
std::unique_ptr<web::DataResponseProvider> provider(new TestResponseProvider);
web::test::SetUpHttpServer(std::move(provider));
LanguageDetectionController::DetectionDetails expectedLanguageDetails;
translate::LanguageDetectionDetails expectedLanguageDetails;
// Detection works when clicking on a link.
GURL URL = web::test::HttpServer::MakeUrl(std::string("http://") + kLinkPath);
......@@ -557,7 +553,7 @@ using translate::LanguageDetectionController;
[ChromeEarlGrey loadURL:URL];
// Check that language has been detected.
LanguageDetectionController::DetectionDetails expectedLanguageDetails;
translate::LanguageDetectionDetails expectedLanguageDetails;
expectedLanguageDetails.html_root_language = "fr";
expectedLanguageDetails.adopted_language = "fr";
[self assertLanguageDetails:expectedLanguageDetails];
......@@ -815,7 +811,7 @@ using translate::LanguageDetectionController;
// Waits until a language has been detected and checks the language details.
- (void)assertLanguageDetails:
(const LanguageDetectionController::DetectionDetails&)expectedDetails {
(const translate::LanguageDetectionDetails&)expectedDetails {
GREYAssert(testing::WaitUntilConditionOrTimeout(
2.0,
^{
......@@ -823,7 +819,7 @@ using translate::LanguageDetectionController;
}),
@"Language not detected");
LanguageDetectionController::DetectionDetails details =
translate::LanguageDetectionDetails details =
*_language_detection_details.get();
_language_detection_details.reset();
......
......@@ -72,6 +72,13 @@ const NSInteger CWVTranslationErrorScriptLoadError =
_webState = webState;
ios_web_view::WebViewTranslateClient::CreateForWebState(_webState);
language::IOSLanguageDetectionTabHelper::CreateForWebState(
_webState,
ios_web_view::WebViewTranslateClient::FromWebState(_webState)
->GetTranslateDriver()
->CreateLanguageDetectionCallback(),
nullptr /* url_language_histogram */);
_translateClient =
ios_web_view::WebViewTranslateClient::FromWebState(_webState);
_translateClient->set_translation_controller(self);
......
......@@ -53,14 +53,8 @@ class WebViewTranslateClient
return translate_manager_.get();
}
private:
friend class web::WebStateUserData<WebViewTranslateClient>;
// The lifetime of WebViewTranslateClient is managed by WebStateUserData.
explicit WebViewTranslateClient(web::WebState* web_state);
// TranslateClient implementation.
translate::TranslateDriver* GetTranslateDriver() override;
translate::IOSTranslateDriver* GetTranslateDriver() override;
PrefService* GetPrefs() override;
std::unique_ptr<translate::TranslatePrefs> GetTranslatePrefs() override;
translate::TranslateAcceptLanguages* GetTranslateAcceptLanguages() override;
......@@ -79,6 +73,12 @@ class WebViewTranslateClient
bool IsTranslatableURL(const GURL& url) override;
void ShowReportLanguageDetectionErrorUI(const GURL& report_url) override;
private:
friend class web::WebStateUserData<WebViewTranslateClient>;
// The lifetime of WebViewTranslateClient is managed by WebStateUserData.
explicit WebViewTranslateClient(web::WebState* web_state);
// web::WebStateObserver implementation.
void WebStateDestroyed(web::WebState* web_state) override;
......
......@@ -56,8 +56,7 @@ WebViewTranslateClient::WebViewTranslateClient(web::WebState* web_state)
nullptr /* language_model */)),
translate_driver_(web_state,
web_state->GetNavigationManager(),
translate_manager_.get(),
nullptr /* language_histogram */) {}
translate_manager_.get()) {}
WebViewTranslateClient::~WebViewTranslateClient() = default;
......@@ -82,7 +81,7 @@ void WebViewTranslateClient::ShowTranslateUI(
triggeredFromMenu:triggered_from_menu];
}
translate::TranslateDriver* WebViewTranslateClient::GetTranslateDriver() {
translate::IOSTranslateDriver* WebViewTranslateClient::GetTranslateDriver() {
return &translate_driver_;
}
......
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