| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 #include "components/translate/core/browser/translate_ranker_impl.h" | 5 #include "components/translate/core/browser/translate_ranker_impl.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 | 78 |
| 79 const base::Feature kTranslateRankerQuery{"TranslateRankerQuery", | 79 const base::Feature kTranslateRankerQuery{"TranslateRankerQuery", |
| 80 base::FEATURE_DISABLED_BY_DEFAULT}; | 80 base::FEATURE_DISABLED_BY_DEFAULT}; |
| 81 | 81 |
| 82 const base::Feature kTranslateRankerEnforcement{ | 82 const base::Feature kTranslateRankerEnforcement{ |
| 83 "TranslateRankerEnforcement", base::FEATURE_DISABLED_BY_DEFAULT}; | 83 "TranslateRankerEnforcement", base::FEATURE_DISABLED_BY_DEFAULT}; |
| 84 | 84 |
| 85 const base::Feature kTranslateRankerLogging{"TranslateRankerLogging", | 85 const base::Feature kTranslateRankerLogging{"TranslateRankerLogging", |
| 86 base::FEATURE_ENABLED_BY_DEFAULT}; | 86 base::FEATURE_ENABLED_BY_DEFAULT}; |
| 87 | 87 |
| 88 const base::Feature kTranslateRankerDecisionOverride{ |
| 89 "TranslateRankerDecisionOverride", base::FEATURE_DISABLED_BY_DEFAULT}; |
| 90 |
| 88 TranslateRankerFeatures::TranslateRankerFeatures() {} | 91 TranslateRankerFeatures::TranslateRankerFeatures() {} |
| 89 | 92 |
| 90 TranslateRankerFeatures::TranslateRankerFeatures(int accepted, | 93 TranslateRankerFeatures::TranslateRankerFeatures(int accepted, |
| 91 int denied, | 94 int denied, |
| 92 int ignored, | 95 int ignored, |
| 93 const std::string& src, | 96 const std::string& src, |
| 94 const std::string& dst, | 97 const std::string& dst, |
| 95 const std::string& cntry, | 98 const std::string& cntry, |
| 96 const std::string& locale) | 99 const std::string& locale) |
| 97 : accepted_count(accepted), | 100 : accepted_count(accepted), |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 | 139 |
| 137 TranslateRankerImpl::TranslateRankerImpl(const base::FilePath& model_path, | 140 TranslateRankerImpl::TranslateRankerImpl(const base::FilePath& model_path, |
| 138 const GURL& model_url, | 141 const GURL& model_url, |
| 139 ukm::UkmService* ukm_service) | 142 ukm::UkmService* ukm_service) |
| 140 : ukm_service_(ukm_service), | 143 : ukm_service_(ukm_service), |
| 141 is_logging_enabled_( | 144 is_logging_enabled_( |
| 142 base::FeatureList::IsEnabled(kTranslateRankerLogging)), | 145 base::FeatureList::IsEnabled(kTranslateRankerLogging)), |
| 143 is_query_enabled_(base::FeatureList::IsEnabled(kTranslateRankerQuery)), | 146 is_query_enabled_(base::FeatureList::IsEnabled(kTranslateRankerQuery)), |
| 144 is_enforcement_enabled_( | 147 is_enforcement_enabled_( |
| 145 base::FeatureList::IsEnabled(kTranslateRankerEnforcement)), | 148 base::FeatureList::IsEnabled(kTranslateRankerEnforcement)), |
| 149 is_decision_override_enabled_(base::FeatureList::IsEnabled( |
| 150 translate::kTranslateRankerDecisionOverride)), |
| 146 weak_ptr_factory_(this) { | 151 weak_ptr_factory_(this) { |
| 147 if (IsQueryEnabled() || IsEnforcementEnabled()) { | 152 if (is_query_enabled_ || is_enforcement_enabled_ || |
| 153 is_decision_override_enabled_) { |
| 148 model_loader_ = base::MakeUnique<RankerModelLoader>( | 154 model_loader_ = base::MakeUnique<RankerModelLoader>( |
| 149 base::Bind(&ValidateModel), | 155 base::Bind(&ValidateModel), |
| 150 base::Bind(&TranslateRankerImpl::OnModelAvailable, | 156 base::Bind(&TranslateRankerImpl::OnModelAvailable, |
| 151 weak_ptr_factory_.GetWeakPtr()), | 157 weak_ptr_factory_.GetWeakPtr()), |
| 152 model_path, model_url, kUmaPrefix); | 158 model_path, model_url, kUmaPrefix); |
| 153 model_loader_->Start(); | 159 model_loader_->Start(); |
| 154 } | 160 } |
| 155 } | 161 } |
| 156 | 162 |
| 157 TranslateRankerImpl::~TranslateRankerImpl() {} | 163 TranslateRankerImpl::~TranslateRankerImpl() {} |
| (...skipping 24 matching lines...) Expand all Loading... |
| 182 | 188 |
| 183 DVLOG(3) << switches::kTranslateRankerModelURL << " = " << raw_url; | 189 DVLOG(3) << switches::kTranslateRankerModelURL << " = " << raw_url; |
| 184 | 190 |
| 185 return GURL(raw_url); | 191 return GURL(raw_url); |
| 186 } | 192 } |
| 187 | 193 |
| 188 void TranslateRankerImpl::EnableLogging(bool value) { | 194 void TranslateRankerImpl::EnableLogging(bool value) { |
| 189 is_logging_enabled_ = value; | 195 is_logging_enabled_ = value; |
| 190 } | 196 } |
| 191 | 197 |
| 192 bool TranslateRankerImpl::IsLoggingEnabled() { | 198 uint32_t TranslateRankerImpl::GetModelVersion() const { |
| 193 return is_logging_enabled_; | |
| 194 } | |
| 195 | |
| 196 bool TranslateRankerImpl::IsQueryEnabled() { | |
| 197 return is_query_enabled_; | |
| 198 } | |
| 199 | |
| 200 bool TranslateRankerImpl::IsEnforcementEnabled() { | |
| 201 return is_enforcement_enabled_; | |
| 202 } | |
| 203 | |
| 204 int TranslateRankerImpl::GetModelVersion() const { | |
| 205 return model_ ? model_->proto().translate().version() : 0; | 199 return model_ ? model_->proto().translate().version() : 0; |
| 206 } | 200 } |
| 207 | 201 |
| 208 bool TranslateRankerImpl::ShouldOfferTranslation( | 202 bool TranslateRankerImpl::ShouldOfferTranslation( |
| 209 const TranslatePrefs& translate_prefs, | 203 const TranslatePrefs& translate_prefs, |
| 210 const std::string& src_lang, | 204 const std::string& src_lang, |
| 211 const std::string& dst_lang) { | 205 const std::string& dst_lang, |
| 206 metrics::TranslateEventProto* translate_event) { |
| 212 DCHECK(sequence_checker_.CalledOnValidSequence()); | 207 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 213 // The ranker is a gate in the "show a translation prompt" flow. To retain | 208 // The ranker is a gate in the "show a translation prompt" flow. To retain |
| 214 // the pre-existing functionality, it defaults to returning true in the | 209 // the pre-existing functionality, it defaults to returning true in the |
| 215 // absence of a model or if enforcement is disabled. As this is ranker is | 210 // absence of a model or if enforcement is disabled. As this is ranker is |
| 216 // subsumed into a more general assist ranker, this default will go away | 211 // subsumed into a more general assist ranker, this default will go away |
| 217 // (or become False). | 212 // (or become False). |
| 218 const bool kDefaultResponse = true; | 213 const bool kDefaultResponse = true; |
| 219 | 214 |
| 215 translate_event->set_ranker_request_timestamp_sec( |
| 216 (base::TimeTicks::Now() - base::TimeTicks()).InSeconds()); |
| 217 translate_event->set_ranker_version(GetModelVersion()); |
| 218 |
| 219 if (!is_query_enabled_ && !is_enforcement_enabled_ && |
| 220 !is_decision_override_enabled_) { |
| 221 translate_event->set_ranker_response( |
| 222 metrics::TranslateEventProto::NOT_QUERIED); |
| 223 return kDefaultResponse; |
| 224 } |
| 225 |
| 220 if (model_loader_) | 226 if (model_loader_) |
| 221 model_loader_->NotifyOfRankerActivity(); | 227 model_loader_->NotifyOfRankerActivity(); |
| 222 | 228 |
| 223 // If we don't have a model, request one and return the default. | 229 // If we don't have a model, request one and return the default. |
| 224 if (model_ == nullptr) { | 230 if (model_ == nullptr) { |
| 231 translate_event->set_ranker_response( |
| 232 metrics::TranslateEventProto::NOT_QUERIED); |
| 225 return kDefaultResponse; | 233 return kDefaultResponse; |
| 226 } | 234 } |
| 227 | 235 |
| 228 SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.ShouldOfferTranslation"); | 236 SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.ShouldOfferTranslation"); |
| 229 | 237 |
| 230 // TODO(rogerm): Remove ScopedTracker below once crbug.com/646711 is closed. | 238 // TODO(rogerm): Remove ScopedTracker below once crbug.com/646711 is closed. |
| 231 tracked_objects::ScopedTracker tracking_profile( | 239 tracked_objects::ScopedTracker tracking_profile( |
| 232 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 240 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 233 "646711 translate::TranslateRankerImpl::ShouldOfferTranslation")); | 241 "646711 translate::TranslateRankerImpl::ShouldOfferTranslation")); |
| 234 | 242 |
| 235 TranslateRankerFeatures features( | 243 TranslateRankerFeatures features( |
| 236 translate_prefs, src_lang, dst_lang, | 244 translate_prefs, src_lang, dst_lang, |
| 237 TranslateDownloadManager::GetInstance()->application_locale()); | 245 TranslateDownloadManager::GetInstance()->application_locale()); |
| 238 | 246 |
| 239 double score = CalculateScore(features); | 247 double score = CalculateScore(features); |
| 240 | 248 |
| 241 DVLOG(2) << "TranslateRankerImpl::ShouldOfferTranslation: " | 249 DVLOG(2) << "TranslateRankerImpl::ShouldOfferTranslation: " |
| 242 << "Score = " << score << ", Features=[" << features << "]"; | 250 << "Score = " << score << ", Features=[" << features << "]"; |
| 243 | 251 |
| 244 bool result = (score >= kTranslationOfferThreshold); | 252 bool result = (score >= kTranslationOfferThreshold); |
| 245 | 253 |
| 246 UMA_HISTOGRAM_BOOLEAN("Translate.Ranker.QueryResult", result); | 254 UMA_HISTOGRAM_BOOLEAN("Translate.Ranker.QueryResult", result); |
| 247 | 255 |
| 256 translate_event->set_ranker_response( |
| 257 result ? metrics::TranslateEventProto::SHOW |
| 258 : metrics::TranslateEventProto::DONT_SHOW); |
| 259 |
| 260 if (!is_enforcement_enabled_ && !is_decision_override_enabled_) { |
| 261 return kDefaultResponse; |
| 262 } |
| 263 |
| 248 return result; | 264 return result; |
| 249 } | 265 } |
| 250 | 266 |
| 251 double TranslateRankerImpl::CalculateScore( | 267 double TranslateRankerImpl::CalculateScore( |
| 252 const TranslateRankerFeatures& features) { | 268 const TranslateRankerFeatures& features) { |
| 253 DCHECK(sequence_checker_.CalledOnValidSequence()); | 269 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 254 SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.CalculateScore"); | 270 SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.CalculateScore"); |
| 255 DCHECK(model_ != nullptr); | 271 DCHECK(model_ != nullptr); |
| 256 const TranslateRankerModel::LogisticRegressionModel& logit = | 272 const TranslateRankerModel::LogisticRegressionModel& logit = |
| 257 model_->proto().translate().logistic_regression_model(); | 273 model_->proto().translate().logistic_regression_model(); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 builder->AddMetric("IgnoreCount", event.ignore_count()); | 320 builder->AddMetric("IgnoreCount", event.ignore_count()); |
| 305 builder->AddMetric("RankerVersion", event.ranker_version()); | 321 builder->AddMetric("RankerVersion", event.ranker_version()); |
| 306 builder->AddMetric("RankerResponse", event.ranker_response()); | 322 builder->AddMetric("RankerResponse", event.ranker_response()); |
| 307 builder->AddMetric("EventType", event.event_type()); | 323 builder->AddMetric("EventType", event.event_type()); |
| 308 } | 324 } |
| 309 | 325 |
| 310 void TranslateRankerImpl::AddTranslateEvent( | 326 void TranslateRankerImpl::AddTranslateEvent( |
| 311 const metrics::TranslateEventProto& event, | 327 const metrics::TranslateEventProto& event, |
| 312 const GURL& url) { | 328 const GURL& url) { |
| 313 DCHECK(sequence_checker_.CalledOnValidSequence()); | 329 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 314 if (IsLoggingEnabled()) { | 330 if (is_logging_enabled_) { |
| 315 DVLOG(3) << "Adding translate ranker event."; | 331 DVLOG(3) << "Adding translate ranker event."; |
| 316 if (url.is_valid()) { | 332 if (url.is_valid()) { |
| 317 SendEventToUKM(event, url); | 333 SendEventToUKM(event, url); |
| 318 } | 334 } |
| 319 event_cache_.push_back(event); | 335 event_cache_.push_back(event); |
| 320 } | 336 } |
| 321 } | 337 } |
| 322 | 338 |
| 323 void TranslateRankerImpl::OnModelAvailable(std::unique_ptr<RankerModel> model) { | 339 void TranslateRankerImpl::OnModelAvailable(std::unique_ptr<RankerModel> model) { |
| 324 DCHECK(sequence_checker_.CalledOnValidSequence()); | 340 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 325 model_ = std::move(model); | 341 model_ = std::move(model); |
| 326 } | 342 } |
| 327 | 343 |
| 328 bool TranslateRankerImpl::CheckModelLoaderForTesting() { | 344 bool TranslateRankerImpl::CheckModelLoaderForTesting() { |
| 329 return model_loader_ != nullptr; | 345 return model_loader_ != nullptr; |
| 330 } | 346 } |
| 331 | 347 |
| 348 void TranslateRankerImpl::RecordTranslateEvent( |
| 349 int event_type, |
| 350 const GURL& url, |
| 351 metrics::TranslateEventProto* translate_event) { |
| 352 DCHECK(metrics::TranslateEventProto::EventType_IsValid(event_type)); |
| 353 translate_event->set_event_type( |
| 354 static_cast<metrics::TranslateEventProto::EventType>(event_type)); |
| 355 translate_event->set_event_timestamp_sec( |
| 356 (base::TimeTicks::Now() - base::TimeTicks()).InSeconds()); |
| 357 AddTranslateEvent(*translate_event, url); |
| 358 } |
| 359 |
| 360 bool TranslateRankerImpl::ShouldOverrideDecision( |
| 361 int event_type, |
| 362 const GURL& url, |
| 363 metrics::TranslateEventProto* translate_event) { |
| 364 DCHECK(metrics::TranslateEventProto::EventType_IsValid(event_type)); |
| 365 if (is_decision_override_enabled_) { |
| 366 translate_event->add_decision_overrides( |
| 367 static_cast<metrics::TranslateEventProto::EventType>(event_type)); |
| 368 DVLOG(3) << "Overriding decision of type: " << event_type; |
| 369 return true; |
| 370 } else { |
| 371 RecordTranslateEvent(event_type, url, translate_event); |
| 372 return false; |
| 373 } |
| 374 } |
| 375 |
| 332 } // namespace translate | 376 } // namespace translate |
| 333 | 377 |
| 334 std::ostream& operator<<(std::ostream& stream, | 378 std::ostream& operator<<(std::ostream& stream, |
| 335 const translate::TranslateRankerFeatures& features) { | 379 const translate::TranslateRankerFeatures& features) { |
| 336 features.WriteTo(stream); | 380 features.WriteTo(stream); |
| 337 return stream; | 381 return stream; |
| 338 } | 382 } |
| OLD | NEW |