Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 "chrome/browser/translate/chrome_translate_client.h" | 5 #include "chrome/browser/translate/chrome_translate_client.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 43 #include "components/translate/core/browser/translate_prefs.h" | 43 #include "components/translate/core/browser/translate_prefs.h" |
| 44 #include "components/translate/core/common/language_detection_details.h" | 44 #include "components/translate/core/common/language_detection_details.h" |
| 45 #include "components/variations/service/variations_service.h" | 45 #include "components/variations/service/variations_service.h" |
| 46 #include "content/public/browser/navigation_entry.h" | 46 #include "content/public/browser/navigation_entry.h" |
| 47 #include "content/public/browser/notification_service.h" | 47 #include "content/public/browser/notification_service.h" |
| 48 #include "content/public/browser/render_view_host.h" | 48 #include "content/public/browser/render_view_host.h" |
| 49 #include "content/public/browser/web_contents.h" | 49 #include "content/public/browser/web_contents.h" |
| 50 #include "url/gurl.h" | 50 #include "url/gurl.h" |
| 51 | 51 |
| 52 namespace { | 52 namespace { |
| 53 using metrics::TranslateEventProto; | |
| 53 | 54 |
| 54 metrics::TranslateEventProto::EventType BubbleResultToTranslateEvent( | 55 TranslateEventProto::EventType BubbleResultToTranslateEvent( |
| 55 ShowTranslateBubbleResult result) { | 56 ShowTranslateBubbleResult result) { |
| 56 switch (result) { | 57 switch (result) { |
| 57 case ShowTranslateBubbleResult::BROWSER_WINDOW_NOT_VALID: | 58 case ShowTranslateBubbleResult::BROWSER_WINDOW_NOT_VALID: |
| 58 return metrics::TranslateEventProto::BROWSER_WINDOW_IS_INVALID; | 59 return TranslateEventProto::BROWSER_WINDOW_IS_INVALID; |
| 59 case ShowTranslateBubbleResult::BROWSER_WINDOW_MINIMIZED: | 60 case ShowTranslateBubbleResult::BROWSER_WINDOW_MINIMIZED: |
| 60 return metrics::TranslateEventProto::BROWSER_WINDOW_IS_MINIMIZED; | 61 return TranslateEventProto::BROWSER_WINDOW_IS_MINIMIZED; |
| 61 case ShowTranslateBubbleResult::BROWSER_WINDOW_NOT_ACTIVE: | 62 case ShowTranslateBubbleResult::BROWSER_WINDOW_NOT_ACTIVE: |
| 62 return metrics::TranslateEventProto::BROWSER_WINDOW_NOT_ACTIVE; | 63 return TranslateEventProto::BROWSER_WINDOW_NOT_ACTIVE; |
| 63 case ShowTranslateBubbleResult::WEB_CONTENTS_NOT_ACTIVE: | 64 case ShowTranslateBubbleResult::WEB_CONTENTS_NOT_ACTIVE: |
| 64 return metrics::TranslateEventProto::WEB_CONTENTS_NOT_ACTIVE; | 65 return TranslateEventProto::WEB_CONTENTS_NOT_ACTIVE; |
| 65 case ShowTranslateBubbleResult::EDITABLE_FIELD_IS_ACTIVE: | 66 case ShowTranslateBubbleResult::EDITABLE_FIELD_IS_ACTIVE: |
| 66 return metrics::TranslateEventProto::EDITABLE_FIELD_IS_ACTIVE; | 67 return TranslateEventProto::EDITABLE_FIELD_IS_ACTIVE; |
| 67 default: | 68 default: |
| 68 NOTREACHED(); | 69 NOTREACHED(); |
| 69 return metrics::TranslateEventProto::UNKNOWN; | 70 return metrics::TranslateEventProto::UNKNOWN; |
| 70 } | 71 } |
| 71 } | 72 } |
| 72 | 73 |
| 74 // ========== LOG LANGUAGE DETECTION EVENT ============== | |
| 75 | |
| 73 std::unique_ptr<sync_pb::UserEventSpecifics> ConstructLanguageDetectionEvent( | 76 std::unique_ptr<sync_pb::UserEventSpecifics> ConstructLanguageDetectionEvent( |
| 74 const int entry_id, | 77 const int entry_id, |
| 75 const translate::LanguageDetectionDetails& details) { | 78 const translate::LanguageDetectionDetails& details) { |
| 76 auto specifics = base::MakeUnique<sync_pb::UserEventSpecifics>(); | 79 auto specifics = base::MakeUnique<sync_pb::UserEventSpecifics>(); |
| 77 specifics->set_event_time_usec(base::Time::Now().ToInternalValue()); | 80 specifics->set_event_time_usec(base::Time::Now().ToInternalValue()); |
| 78 | 81 |
| 79 // TODO(renjieliu): Revisit this field when the best way to identify | 82 // TODO(renjieliu): Revisit this field when the best way to identify |
| 80 // navigations is determined. | 83 // navigations is determined. |
| 81 specifics->set_navigation_id(base::Time::Now().ToInternalValue()); | 84 specifics->set_navigation_id(base::Time::Now().ToInternalValue()); |
| 82 | 85 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 106 | 109 |
| 107 // If entry is null, we don't record the page. | 110 // If entry is null, we don't record the page. |
| 108 // The navigation entry can be null in situations like download or initial | 111 // The navigation entry can be null in situations like download or initial |
| 109 // blank page. | 112 // blank page. |
| 110 if (entry != nullptr) { | 113 if (entry != nullptr) { |
| 111 user_event_service->RecordUserEvent( | 114 user_event_service->RecordUserEvent( |
| 112 ConstructLanguageDetectionEvent(entry->GetUniqueID(), details)); | 115 ConstructLanguageDetectionEvent(entry->GetUniqueID(), details)); |
| 113 } | 116 } |
| 114 } | 117 } |
| 115 | 118 |
| 119 // ========== LOG TRANSLATE EVENT ============== | |
| 120 | |
| 121 bool ConstructTranslateEvent(const int entry_id, | |
|
amoylan
2017/05/30 03:10:56
Can we add a comment atop this function? particula
renjieliu1
2017/05/30 03:33:24
Done.
| |
| 122 const TranslateEventProto& translate_event, | |
| 123 sync_pb::UserEventSpecifics* const specifics) { | |
| 124 specifics->set_event_time_usec(base::Time::Now().ToInternalValue()); | |
| 125 | |
| 126 // TODO(renjieliu): Revisit this field when the best way to identify | |
| 127 // navigations is determined. | |
| 128 specifics->set_navigation_id(base::Time::Now().ToInternalValue()); | |
| 129 auto* const translation = specifics->mutable_translation(); | |
| 130 translation->set_from_language_code(translate_event.source_language()); | |
| 131 translation->set_to_language_code(translate_event.target_language()); | |
| 132 switch (translate_event.event_type()) { | |
| 133 case TranslateEventProto::UNKNOWN: | |
| 134 translation->set_interaction(sync_pb::Translation::UNKNOWN); | |
| 135 break; | |
| 136 case TranslateEventProto::USER_ACCEPT: | |
| 137 if (translate_event.has_modified_source_language() || | |
| 138 translate_event.has_modified_target_language()) { | |
| 139 // Special case, since we don't have event enum telling us it's actually | |
| 140 // modified by user, we do this by check whether this event has modified | |
| 141 // source or target language. | |
| 142 translation->set_from_language_code( | |
| 143 translate_event.modified_source_language()); | |
| 144 translation->set_to_language_code( | |
| 145 translate_event.modified_target_language()); | |
| 146 translation->set_interaction(sync_pb::Translation::MANUAL); | |
| 147 } else { | |
| 148 translation->set_interaction(sync_pb::Translation::ACCEPTED); | |
| 149 } | |
| 150 break; | |
| 151 case TranslateEventProto::USER_DECLINE: | |
|
napper
2017/05/30 02:56:26
I think we should keep the naming consistent (i.e.
renjieliu1
2017/05/30 03:33:24
Done. Changed the proto as well.
| |
| 152 translation->set_interaction(sync_pb::Translation::REJECTED); | |
| 153 break; | |
| 154 case TranslateEventProto::USER_IGNORE: | |
| 155 translation->set_interaction(sync_pb::Translation::IGNORED); | |
| 156 break; | |
| 157 case TranslateEventProto::USER_DISMISS: | |
| 158 translation->set_interaction(sync_pb::Translation::DISMISSED); | |
| 159 break; | |
| 160 case TranslateEventProto::USER_REVERT: | |
| 161 translation->set_interaction(sync_pb::Translation::TRANSLATION_REVERTED); | |
| 162 break; | |
| 163 case TranslateEventProto::AUTOMATICALLY_TRANSLATED: | |
| 164 translation->set_interaction(sync_pb::Translation::AUTOMATIC_TRANSLATION); | |
| 165 break; | |
| 166 default: // We don't care about other events. | |
| 167 return false; | |
| 168 } | |
| 169 return true; | |
| 170 } | |
| 171 | |
| 172 void LogTranslateEvent(const content::WebContents* const web_contents, | |
| 173 const metrics::TranslateEventProto& translate_event) { | |
| 174 auto* const profile = | |
|
amoylan
2017/05/30 03:10:56
Do you want to DCHECK web_contents != nullptr?
Act
renjieliu1
2017/05/30 03:33:24
Done.
| |
| 175 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | |
| 176 | |
| 177 syncer::UserEventService* const user_event_service = | |
| 178 browser_sync::UserEventServiceFactory::GetForProfile(profile); | |
| 179 | |
| 180 const auto* const entry = | |
| 181 web_contents->GetController().GetLastCommittedEntry(); | |
| 182 | |
| 183 // If entry is null, we don't record the page. | |
| 184 // The navigation entry can be null in situations like download or initial | |
| 185 // blank page. | |
| 186 if (entry == nullptr) | |
| 187 return; | |
| 188 | |
| 189 auto specifics = base::MakeUnique<sync_pb::UserEventSpecifics>(); | |
| 190 // We only log the event we care about. | |
| 191 const bool needs_logging = ConstructTranslateEvent( | |
| 192 entry->GetUniqueID(), translate_event, specifics.get()); | |
| 193 if (needs_logging) { | |
| 194 user_event_service->RecordUserEvent(std::move(specifics)); | |
| 195 } | |
| 196 } | |
| 197 | |
| 116 } // namespace | 198 } // namespace |
| 117 | 199 |
| 118 DEFINE_WEB_CONTENTS_USER_DATA_KEY(ChromeTranslateClient); | 200 DEFINE_WEB_CONTENTS_USER_DATA_KEY(ChromeTranslateClient); |
| 119 | 201 |
| 120 ChromeTranslateClient::ChromeTranslateClient(content::WebContents* web_contents) | 202 ChromeTranslateClient::ChromeTranslateClient(content::WebContents* web_contents) |
| 121 : content::WebContentsObserver(web_contents), | 203 : content::WebContentsObserver(web_contents), |
| 122 translate_driver_(&web_contents->GetController()), | 204 translate_driver_(&web_contents->GetController()), |
| 123 translate_manager_(new translate::TranslateManager( | 205 translate_manager_(new translate::TranslateManager( |
| 124 this, | 206 this, |
| 125 translate::TranslateRankerFactory::GetForBrowserContext( | 207 translate::TranslateRankerFactory::GetForBrowserContext( |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 210 if (!auto_translate_language.empty()) { | 292 if (!auto_translate_language.empty()) { |
| 211 *target = auto_translate_language; | 293 *target = auto_translate_language; |
| 212 return; | 294 return; |
| 213 } | 295 } |
| 214 } | 296 } |
| 215 | 297 |
| 216 *target = | 298 *target = |
| 217 translate::TranslateManager::GetTargetLanguage(translate_prefs.get()); | 299 translate::TranslateManager::GetTargetLanguage(translate_prefs.get()); |
| 218 } | 300 } |
| 219 | 301 |
| 302 void ChromeTranslateClient::RecordTranslateEvent( | |
| 303 const TranslateEventProto& translate_event) { | |
| 304 LogTranslateEvent(web_contents(), translate_event); | |
| 305 } | |
| 306 | |
| 220 // static | 307 // static |
| 221 void ChromeTranslateClient::BindContentTranslateDriver( | 308 void ChromeTranslateClient::BindContentTranslateDriver( |
| 222 content::RenderFrameHost* render_frame_host, | 309 content::RenderFrameHost* render_frame_host, |
| 223 const service_manager::BindSourceInfo& source_info, | 310 const service_manager::BindSourceInfo& source_info, |
| 224 translate::mojom::ContentTranslateDriverRequest request) { | 311 translate::mojom::ContentTranslateDriverRequest request) { |
| 225 content::WebContents* web_contents = | 312 content::WebContents* web_contents = |
| 226 content::WebContents::FromRenderFrameHost(render_frame_host); | 313 content::WebContents::FromRenderFrameHost(render_frame_host); |
| 227 if (!web_contents) | 314 if (!web_contents) |
| 228 return; | 315 return; |
| 229 | 316 |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 413 return ShowTranslateBubbleResult::SUCCESS; | 500 return ShowTranslateBubbleResult::SUCCESS; |
| 414 } | 501 } |
| 415 | 502 |
| 416 return TranslateBubbleFactory::Show(browser->window(), web_contents(), step, | 503 return TranslateBubbleFactory::Show(browser->window(), web_contents(), step, |
| 417 error_type); | 504 error_type); |
| 418 #else | 505 #else |
| 419 NOTREACHED(); | 506 NOTREACHED(); |
| 420 return ShowTranslateBubbleResult::SUCCESS; | 507 return ShowTranslateBubbleResult::SUCCESS; |
| 421 #endif | 508 #endif |
| 422 } | 509 } |
| OLD | NEW |