 Chromium Code Reviews
 Chromium Code Reviews Issue 2872083003:
  Added translation policy API.  (Closed)
    
  
    Issue 2872083003:
  Added translation policy API.  (Closed) 
  | OLD | NEW | 
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #import "ios/web_view/internal/translate/cwv_translation_controller_internal.h" | 5 #import "ios/web_view/internal/translate/cwv_translation_controller_internal.h" | 
| 6 | 6 | 
| 7 #include <string> | 7 #include <string> | 
| 8 | 8 | 
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" | 
| 10 #include "base/strings/string16.h" | 10 #include "base/strings/string16.h" | 
| 11 #include "base/strings/sys_string_conversions.h" | |
| 12 #include "components/translate/core/browser/translate_download_manager.h" | |
| 11 #include "components/translate/core/browser/translate_manager.h" | 13 #include "components/translate/core/browser/translate_manager.h" | 
| 12 #include "components/translate/core/browser/translate_ui_delegate.h" | |
| 13 #import "ios/web_view/internal/translate/cwv_language_detection_result_internal. h" | 14 #import "ios/web_view/internal/translate/cwv_language_detection_result_internal. h" | 
| 14 #import "ios/web_view/internal/translate/cwv_translation_language_internal.h" | 15 #import "ios/web_view/internal/translate/cwv_translation_language_internal.h" | 
| 15 #import "ios/web_view/internal/translate/web_view_translate_client.h" | 16 #import "ios/web_view/internal/translate/web_view_translate_client.h" | 
| 16 #import "ios/web_view/public/cwv_translation_controller_delegate.h" | 17 #import "ios/web_view/public/cwv_translation_controller_delegate.h" | 
| 18 #import "ios/web_view/public/cwv_translation_policy.h" | |
| 19 #include "ui/base/l10n/l10n_util.h" | |
| 17 | 20 | 
| 18 #if !defined(__has_feature) || !__has_feature(objc_arc) | 21 #if !defined(__has_feature) || !__has_feature(objc_arc) | 
| 19 #error "This file requires ARC support." | 22 #error "This file requires ARC support." | 
| 20 #endif | 23 #endif | 
| 21 | 24 | 
| 22 NSErrorDomain const CWVTranslationErrorDomain = | 25 NSErrorDomain const CWVTranslationErrorDomain = | 
| 23 @"org.chromium.chromewebview.TranslationErrorDomain"; | 26 @"org.chromium.chromewebview.TranslationErrorDomain"; | 
| 24 | 27 | 
| 25 const NSInteger CWVTranslationErrorNetwork = | 28 const NSInteger CWVTranslationErrorNetwork = | 
| 26 translate::TranslateErrors::NETWORK; | 29 translate::TranslateErrors::NETWORK; | 
| (...skipping 11 matching lines...) Expand all Loading... | |
| 38 translate::TranslateErrors::TRANSLATION_TIMEOUT; | 41 translate::TranslateErrors::TRANSLATION_TIMEOUT; | 
| 39 const NSInteger CWVTranslationErrorUnexpectedScriptError = | 42 const NSInteger CWVTranslationErrorUnexpectedScriptError = | 
| 40 translate::TranslateErrors::UNEXPECTED_SCRIPT_ERROR; | 43 translate::TranslateErrors::UNEXPECTED_SCRIPT_ERROR; | 
| 41 const NSInteger CWVTranslationErrorBadOrigin = | 44 const NSInteger CWVTranslationErrorBadOrigin = | 
| 42 translate::TranslateErrors::BAD_ORIGIN; | 45 translate::TranslateErrors::BAD_ORIGIN; | 
| 43 const NSInteger CWVTranslationErrorScriptLoadError = | 46 const NSInteger CWVTranslationErrorScriptLoadError = | 
| 44 translate::TranslateErrors::SCRIPT_LOAD_ERROR; | 47 translate::TranslateErrors::SCRIPT_LOAD_ERROR; | 
| 45 | 48 | 
| 46 @interface CWVTranslationController () | 49 @interface CWVTranslationController () | 
| 47 | 50 | 
| 48 // Convenience method to generate all supported languages from | 51 // Convenience method to get the language with |languageCode|. | 
| 49 // |translateUIDelegate|. | 52 - (CWVTranslationLanguage*)languageWithCode:(NSString*)languageCode; | 
| 
Hiroshi Ichikawa
2017/05/25 06:44:22
Optional: Maybe this method should take const std:
 
jzw1
2017/05/25 06:55:37
Done.
 | |
| 50 - (NSArray<CWVTranslationLanguage*>*)supportedLanguages; | |
| 51 | |
| 52 // Convenience method to get a language at |index| from |translateUIDelegate|. | |
| 53 - (CWVTranslationLanguage*)languageAtIndex:(size_t)index; | |
| 54 | 53 | 
| 55 @end | 54 @end | 
| 56 | 55 | 
| 57 @implementation CWVTranslationController { | 56 @implementation CWVTranslationController { | 
| 58 ios_web_view::WebViewTranslateClient* _translateClient; | 57 ios_web_view::WebViewTranslateClient* _translateClient; | 
| 59 std::unique_ptr<translate::TranslateUIDelegate> _translateUIDelegate; | 58 std::unique_ptr<translate::TranslatePrefs> _translatePrefs; | 
| 59 NSArray<CWVTranslationLanguage*>* _supportedLanguages; | |
| 60 } | 60 } | 
| 61 | 61 | 
| 62 @synthesize delegate = _delegate; | 62 @synthesize delegate = _delegate; | 
| 63 @synthesize webState = _webState; | 63 @synthesize webState = _webState; | 
| 64 | 64 | 
| 65 #pragma mark - Internal Methods | 65 #pragma mark - Internal Methods | 
| 66 | 66 | 
| 67 - (void)setWebState:(web::WebState*)webState { | 67 - (void)setWebState:(web::WebState*)webState { | 
| 68 _webState = webState; | 68 _webState = webState; | 
| 69 | 69 | 
| 70 ios_web_view::WebViewTranslateClient::CreateForWebState(_webState); | 70 ios_web_view::WebViewTranslateClient::CreateForWebState(_webState); | 
| 71 _translateClient = | 71 _translateClient = | 
| 72 ios_web_view::WebViewTranslateClient::FromWebState(_webState); | 72 ios_web_view::WebViewTranslateClient::FromWebState(_webState); | 
| 73 _translateClient->set_translation_controller(self); | 73 _translateClient->set_translation_controller(self); | 
| 74 _translatePrefs = _translateClient->translate_manager() | |
| 75 ->translate_client() | |
| 76 ->GetTranslatePrefs(); | |
| 77 | |
| 78 NSMutableArray<CWVTranslationLanguage*>* supportedLanguages = | |
| 79 [NSMutableArray array]; | |
| 80 std::vector<std::string> language_codes; | |
| 81 translate::TranslateDownloadManager::GetSupportedLanguages(&language_codes); | |
| 82 std::string locale = | |
| 83 translate::TranslateDownloadManager::GetInstance()->application_locale(); | |
| 84 for (std::vector<std::string>::const_iterator iter = language_codes.begin(); | |
| 
Hiroshi Ichikawa
2017/05/25 06:44:22
for (const std::string languageCode : language_cod
 
jzw1
2017/05/25 06:55:37
Done.
 
Hiroshi Ichikawa
2017/05/25 07:42:30
Oops sorry it's better to add "&":
for (const std
 | |
| 85 iter != language_codes.end(); ++iter) { | |
| 86 std::string languageCode = *iter; | |
| 
Hiroshi Ichikawa
2017/05/25 06:44:22
Be consistent with the variable name style between
 
jzw1
2017/05/25 06:55:36
Done.
 | |
| 87 base::string16 languageName = | |
| 88 l10n_util::GetDisplayNameForLocale(languageCode, locale, true); | |
| 89 CWVTranslationLanguage* language = | |
| 90 [[CWVTranslationLanguage alloc] initWithLanguageCode:languageCode | |
| 91 languageName:languageName]; | |
| 92 [supportedLanguages addObject:language]; | |
| 93 } | |
| 94 | |
| 95 [supportedLanguages sortUsingComparator:^NSComparisonResult( | |
| 96 CWVTranslationLanguage* languageA, | |
| 97 CWVTranslationLanguage* languageB) { | |
| 98 return [languageA.languageName compare:languageB.languageName]; | |
| 99 }]; | |
| 100 _supportedLanguages = [supportedLanguages copy]; | |
| 
Hiroshi Ichikawa
2017/05/25 06:44:22
Why do you copy here?
 
jzw1
2017/05/25 06:55:37
the local var is a NSMutableArray so I usually cop
 
Hiroshi Ichikawa
2017/05/25 07:42:30
Oh I see, good to know. I didn't know -[NSMutableA
 | |
| 74 } | 101 } | 
| 75 | 102 | 
| 76 - (void)updateTranslateStep:(translate::TranslateStep)step | 103 - (void)updateTranslateStep:(translate::TranslateStep)step | 
| 77 sourceLanguage:(const std::string&)sourceLanguage | 104 sourceLanguage:(const std::string&)sourceLanguage | 
| 78 targetLanguage:(const std::string&)targetLanguage | 105 targetLanguage:(const std::string&)targetLanguage | 
| 79 errorType:(translate::TranslateErrors::Type)errorType | 106 errorType:(translate::TranslateErrors::Type)errorType | 
| 80 triggeredFromMenu:(bool)triggeredFromMenu { | 107 triggeredFromMenu:(bool)triggeredFromMenu { | 
| 81 translate::TranslateManager* manager = _translateClient->translate_manager(); | |
| 82 _translateUIDelegate = base::MakeUnique<translate::TranslateUIDelegate>( | |
| 83 manager->GetWeakPtr(), sourceLanguage, targetLanguage); | |
| 84 | |
| 85 CWVTranslationLanguage* source = | 108 CWVTranslationLanguage* source = | 
| 86 [self languageAtIndex:_translateUIDelegate->GetOriginalLanguageIndex()]; | 109 [self languageWithCode:base::SysUTF8ToNSString(sourceLanguage)]; | 
| 87 CWVTranslationLanguage* target = | 110 CWVTranslationLanguage* target = | 
| 88 [self languageAtIndex:_translateUIDelegate->GetTargetLanguageIndex()]; | 111 [self languageWithCode:base::SysUTF8ToNSString(targetLanguage)]; | 
| 89 | 112 | 
| 90 NSError* error; | 113 NSError* error; | 
| 91 if (errorType != translate::TranslateErrors::NONE) { | 114 if (errorType != translate::TranslateErrors::NONE) { | 
| 92 error = [NSError errorWithDomain:CWVTranslationErrorDomain | 115 error = [NSError errorWithDomain:CWVTranslationErrorDomain | 
| 93 code:errorType | 116 code:errorType | 
| 94 userInfo:nil]; | 117 userInfo:nil]; | 
| 95 } | 118 } | 
| 96 | 119 | 
| 97 switch (step) { | 120 switch (step) { | 
| 98 case translate::TRANSLATE_STEP_BEFORE_TRANSLATE: { | 121 case translate::TRANSLATE_STEP_BEFORE_TRANSLATE: { | 
| 99 CWVLanguageDetectionResult* languageDetectionResult = | 122 CWVLanguageDetectionResult* languageDetectionResult = | 
| 100 [[CWVLanguageDetectionResult alloc] | 123 [[CWVLanguageDetectionResult alloc] | 
| 101 initWithPageLanguage:source | 124 initWithPageLanguage:source | 
| 102 suggestedTargetLanguage:target | 125 suggestedTargetLanguage:target | 
| 103 supportedLanguages:[self supportedLanguages]]; | 126 supportedLanguages:_supportedLanguages]; | 
| 104 if ([_delegate respondsToSelector:@selector | 127 if ([_delegate respondsToSelector:@selector | 
| 105 (translationController:didFinishLanguageDetectionWithResult | 128 (translationController:didFinishLanguageDetectionWithResult | 
| 106 :error:)]) { | 129 :error:)]) { | 
| 107 [_delegate translationController:self | 130 [_delegate translationController:self | 
| 108 didFinishLanguageDetectionWithResult:languageDetectionResult | 131 didFinishLanguageDetectionWithResult:languageDetectionResult | 
| 109 error:error]; | 132 error:error]; | 
| 110 } | 133 } | 
| 111 break; | 134 break; | 
| 112 } | 135 } | 
| 113 case translate::TRANSLATE_STEP_TRANSLATING: | 136 case translate::TRANSLATE_STEP_TRANSLATING: | 
| (...skipping 19 matching lines...) Expand all Loading... | |
| 133 break; | 156 break; | 
| 134 case translate::TRANSLATE_STEP_TRANSLATE_ERROR: | 157 case translate::TRANSLATE_STEP_TRANSLATE_ERROR: | 
| 135 break; | 158 break; | 
| 136 } | 159 } | 
| 137 } | 160 } | 
| 138 | 161 | 
| 139 #pragma mark - Public Methods | 162 #pragma mark - Public Methods | 
| 140 | 163 | 
| 141 - (void)translatePageFromLanguage:(CWVTranslationLanguage*)sourceLanguage | 164 - (void)translatePageFromLanguage:(CWVTranslationLanguage*)sourceLanguage | 
| 142 toLanguage:(CWVTranslationLanguage*)targetLanguage { | 165 toLanguage:(CWVTranslationLanguage*)targetLanguage { | 
| 143 // TODO(706289): Use the passed parameters. | 166 std::string sourceLanguageCode = | 
| 144 _translateUIDelegate->Translate(); | 167 base::SysNSStringToUTF8(sourceLanguage.languageCode); | 
| 168 std::string targetLanguageCode = | |
| 169 base::SysNSStringToUTF8(targetLanguage.languageCode); | |
| 170 _translateClient->translate_manager()->TranslatePage( | |
| 171 sourceLanguageCode, targetLanguageCode, false); | |
| 145 } | 172 } | 
| 146 | 173 | 
| 147 - (void)revertTranslation { | 174 - (void)revertTranslation { | 
| 148 _translateUIDelegate->RevertTranslation(); | 175 _translateClient->translate_manager()->RevertTranslation(); | 
| 176 } | |
| 177 | |
| 178 - (void)setTranslationPolicy:(CWVTranslationPolicy*)policy | |
| 179 forPageLanguage:(CWVTranslationLanguage*)pageLanguage { | |
| 180 std::string languageCode = base::SysNSStringToUTF8(pageLanguage.languageCode); | |
| 181 switch (policy.type) { | |
| 182 case CWVTranslationPolicyAsk: { | |
| 183 _translatePrefs->UnblockLanguage(languageCode); | |
| 184 _translatePrefs->RemoveLanguagePairFromWhitelist(languageCode, | |
| 185 std::string()); | |
| 186 break; | |
| 187 } | |
| 188 case CWVTranslationPolicyNever: { | |
| 189 _translatePrefs->BlockLanguage(languageCode); | |
| 190 break; | |
| 191 } | |
| 192 case CWVTranslationPolicyAuto: { | |
| 193 _translatePrefs->UnblockLanguage(languageCode); | |
| 194 _translatePrefs->WhitelistLanguagePair( | |
| 195 languageCode, base::SysNSStringToUTF8(policy.language.languageCode)); | |
| 196 break; | |
| 197 } | |
| 198 } | |
| 199 } | |
| 200 | |
| 201 - (CWVTranslationPolicy*)translationPolicyForPageLanguage: | |
| 202 (CWVTranslationLanguage*)pageLanguage { | |
| 203 std::string languageCode = base::SysNSStringToUTF8(pageLanguage.languageCode); | |
| 204 bool isLanguageBlocked = _translatePrefs->IsBlockedLanguage(languageCode); | |
| 205 if (isLanguageBlocked) { | |
| 206 return [CWVTranslationPolicy translationPolicyNever]; | |
| 207 } | |
| 208 | |
| 209 std::string autoTargetLanguageCode; | |
| 210 if (!_translatePrefs->ShouldAutoTranslate(languageCode, | |
| 211 &autoTargetLanguageCode)) { | |
| 212 autoTargetLanguageCode = std::string(); | |
| 
Hiroshi Ichikawa
2017/05/25 06:44:22
How about returning [CWVTranslationPolicy translat
 
jzw1
2017/05/25 06:55:37
Done.
 | |
| 213 } | |
| 214 if (autoTargetLanguageCode.empty()) { | |
| 215 return [CWVTranslationPolicy translationPolicyAsk]; | |
| 216 } | |
| 217 | |
| 218 CWVTranslationLanguage* targetLanguage = | |
| 219 [self languageWithCode:base::SysUTF8ToNSString(autoTargetLanguageCode)]; | |
| 220 return [CWVTranslationPolicy | |
| 221 translationPolicyAutoTranslateToLanguage:targetLanguage]; | |
| 222 } | |
| 223 | |
| 224 - (void)setTranslationPolicy:(CWVTranslationPolicy*)policy | |
| 225 forPageHost:(NSString*)pageHost { | |
| 226 DCHECK(pageHost.length > 0); | |
| 227 switch (policy.type) { | |
| 228 case CWVTranslationPolicyAsk: { | |
| 229 _translatePrefs->RemoveSiteFromBlacklist( | |
| 230 base::SysNSStringToUTF8(pageHost)); | |
| 231 break; | |
| 232 } | |
| 233 case CWVTranslationPolicyNever: { | |
| 234 _translatePrefs->BlacklistSite(base::SysNSStringToUTF8(pageHost)); | |
| 235 break; | |
| 236 } | |
| 237 case CWVTranslationPolicyAuto: { | |
| 238 // TODO(crbug.com/706289): Support auto translation policies for websites. | |
| 239 NOTREACHED(); | |
| 240 break; | |
| 241 } | |
| 242 } | |
| 243 } | |
| 244 | |
| 245 - (CWVTranslationPolicy*)translationPolicyForPageHost:(NSString*)pageHost { | |
| 246 bool isSiteBlackListed = | |
| 247 _translatePrefs->IsSiteBlacklisted(base::SysNSStringToUTF8(pageHost)); | |
| 248 if (isSiteBlackListed) { | |
| 249 return [CWVTranslationPolicy translationPolicyNever]; | |
| 250 } | |
| 251 return [CWVTranslationPolicy translationPolicyAsk]; | |
| 149 } | 252 } | 
| 150 | 253 | 
| 151 #pragma mark - Private Methods | 254 #pragma mark - Private Methods | 
| 152 | 255 | 
| 153 - (NSArray<CWVTranslationLanguage*>*)supportedLanguages { | 256 - (CWVTranslationLanguage*)languageWithCode:(NSString*)languageCode { | 
| 154 NSMutableArray* supportedLanguages = [NSMutableArray array]; | 257 for (CWVTranslationLanguage* language in _supportedLanguages) { | 
| 155 for (size_t i = 0; i < _translateUIDelegate->GetNumberOfLanguages(); i++) { | 258 if ([language.languageCode isEqualToString:languageCode]) { | 
| 156 CWVTranslationLanguage* language = [self languageAtIndex:i]; | 259 return language; | 
| 157 [supportedLanguages addObject:language]; | 260 } | 
| 158 } | 261 } | 
| 159 | 262 return nil; | 
| 160 return [supportedLanguages copy]; | |
| 161 } | |
| 162 | |
| 163 - (CWVTranslationLanguage*)languageAtIndex:(size_t)index { | |
| 164 std::string languageCode = _translateUIDelegate->GetLanguageCodeAt(index); | |
| 165 base::string16 languageName = _translateUIDelegate->GetLanguageNameAt(index); | |
| 166 return [[CWVTranslationLanguage alloc] initWithLanguageCode:languageCode | |
| 167 languageName:languageName]; | |
| 168 } | 263 } | 
| 169 | 264 | 
| 170 @end | 265 @end | 
| OLD | NEW |