Linux: Depend on liberation-fonts package for RPMs.
[chromium-blink-merge.git] / components / translate / ios / browser / language_detection_controller.mm
blob69f37a52f812694fdd58f2b67882eefa233bbe05
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/translate/ios/browser/language_detection_controller.h"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/metrics/histogram.h"
12 #include "base/prefs/pref_member.h"
13 #include "base/time/time.h"
14 #include "components/translate/core/common/translate_pref_names.h"
15 #include "components/translate/core/language_detection/language_detection_util.h"
16 #import "components/translate/ios/browser/js_language_detection_manager.h"
17 #include "ios/web/public/string_util.h"
18 #include "ios/web/public/url_scheme_util.h"
19 #include "ios/web/public/web_state/web_state.h"
21 namespace translate {
23 namespace {
24 // Name for the UMA metric used to track text extraction time.
25 const char kTranslateCaptureText[] = "Translate.CaptureText";
26 // Prefix for the language detection javascript commands. Must be kept in sync
27 // with language_detection.js.
28 const char kCommandPrefix[] = "languageDetection";
31 LanguageDetectionController::LanguageDetectionController(
32     web::WebState* web_state,
33     JsLanguageDetectionManager* manager,
34     PrefService* prefs)
35     : web::WebStateObserver(web_state),
36       js_manager_([manager retain]),
37       weak_method_factory_(this) {
38   DCHECK(web::WebStateObserver::web_state());
39   DCHECK(js_manager_);
40   translate_enabled_.Init(prefs::kEnableTranslate, prefs);
41   web_state->AddScriptCommandCallback(
42       base::Bind(&LanguageDetectionController::OnTextCaptured,
43                  base::Unretained(this)),
44       kCommandPrefix);
47 LanguageDetectionController::~LanguageDetectionController() {
50 scoped_ptr<LanguageDetectionController::CallbackList::Subscription>
51 LanguageDetectionController::RegisterLanguageDetectionCallback(
52     const Callback& callback) {
53   return language_detection_callbacks_.Add(callback);
56 void LanguageDetectionController::StartLanguageDetection() {
57   if (!translate_enabled_.GetValue())
58     return;  // Translate disabled in preferences.
59   DCHECK(web_state());
60   const GURL& url = web_state()->GetVisibleURL();
61   if (!web::UrlHasWebScheme(url) || !web_state()->ContentIsHTML())
62     return;
63   [js_manager_ inject];
64   [js_manager_ startLanguageDetection];
67 bool LanguageDetectionController::OnTextCaptured(
68     const base::DictionaryValue& command,
69     const GURL& url,
70     bool interacting) {
71   std::string textCapturedCommand;
72   if (!command.GetString("command", &textCapturedCommand) ||
73       textCapturedCommand != "languageDetection.textCaptured" ||
74       !command.HasKey("translationAllowed")) {
75     NOTREACHED();
76     return false;
77   }
78   bool translation_allowed = false;
79   command.GetBoolean("translationAllowed", &translation_allowed);
80   if (!translation_allowed) {
81     // Translation not allowed by the page. Done processing.
82     return true;
83   }
84   if (!command.HasKey("captureTextTime") || !command.HasKey("htmlLang") ||
85       !command.HasKey("httpContentLanguage")) {
86     NOTREACHED();
87     return false;
88   }
90   int capture_text_time = 0;
91   command.GetInteger("captureTextTime", &capture_text_time);
92   UMA_HISTOGRAM_TIMES(kTranslateCaptureText,
93                       base::TimeDelta::FromMillisecondsD(capture_text_time));
94   std::string html_lang;
95   command.GetString("htmlLang", &html_lang);
96   std::string http_content_language;
97   command.GetString("httpContentLanguage", &http_content_language);
98   // If there is no language defined in httpEquiv, use the HTTP header.
99   if (http_content_language.empty())
100     http_content_language = web_state()->GetContentLanguageHeader();
102   [js_manager_ retrieveBufferedTextContent:
103                    base::Bind(&LanguageDetectionController::OnTextRetrieved,
104                               weak_method_factory_.GetWeakPtr(),
105                               http_content_language, html_lang)];
106   return true;
109 void LanguageDetectionController::OnTextRetrieved(
110     const std::string& http_content_language,
111     const std::string& html_lang,
112     const base::string16& text_content) {
113   std::string language = translate::DeterminePageLanguage(
114       http_content_language, html_lang,
115       web::GetStringByClippingLastWord(text_content,
116                                        language_detection::kMaxIndexChars),
117       nullptr /* cld_language */, nullptr /* is_cld_reliable */);
118   if (language.empty())
119     return;  // No language detected.
121   DetectionDetails details;
122   details.content_language = http_content_language;
123   details.html_root_language = html_lang;
124   details.adopted_language = language;
125   language_detection_callbacks_.Notify(details);
128 // web::WebStateObserver implementation:
130 void LanguageDetectionController::PageLoaded(
131     web::PageLoadCompletionStatus load_completion_status) {
132   if (load_completion_status == web::PageLoadCompletionStatus::SUCCESS)
133     StartLanguageDetection();
136 void LanguageDetectionController::UrlHashChanged() {
137   StartLanguageDetection();
140 void LanguageDetectionController::HistoryStateChanged() {
141   StartLanguageDetection();
144 void LanguageDetectionController::WebStateDestroyed() {
145   web_state()->RemoveScriptCommandCallback(kCommandPrefix);
148 }  // namespace translate