OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 // The |FeedbackSender| object stores the user feedback to spellcheck | 5 // The |FeedbackSender| object stores the user feedback to spellcheck |
6 // suggestions in a |Feedback| object. | 6 // suggestions in a |Feedback| object. |
7 // | 7 // |
8 // When spelling service returns spellcheck results, these results first arrive | 8 // When spelling service returns spellcheck results, these results first arrive |
9 // in |FeedbackSender| to assign hash identifiers for each | 9 // in |FeedbackSender| to assign hash identifiers for each |
10 // misspelling-suggestion pair. If the spelling service identifies the same | 10 // misspelling-suggestion pair. If the spelling service identifies the same |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
113 params->Set("suggestionInfo", suggestion_info); | 113 params->Set("suggestionInfo", suggestion_info); |
114 params->SetString("key", google_apis::GetAPIKey()); | 114 params->SetString("key", google_apis::GetAPIKey()); |
115 params->SetString("language", language); | 115 params->SetString("language", language); |
116 params->SetString("originCountry", country); | 116 params->SetString("originCountry", country); |
117 params->SetString("clientName", "Chrome"); | 117 params->SetString("clientName", "Chrome"); |
118 return params; | 118 return params; |
119 } | 119 } |
120 | 120 |
121 // Builds feedback data from |params|. Takes ownership of |params|. The caller | 121 // Builds feedback data from |params|. Takes ownership of |params|. The caller |
122 // owns the result. | 122 // owns the result. |
123 base::Value* BuildFeedbackValue(base::DictionaryValue* params) { | 123 base::Value* BuildFeedbackValue(base::DictionaryValue* params, |
124 const std::string& api_version) { | |
124 base::DictionaryValue* result = new base::DictionaryValue; | 125 base::DictionaryValue* result = new base::DictionaryValue; |
125 result->Set("params", params); | 126 result->Set("params", params); |
126 result->SetString("method", "spelling.feedback"); | 127 result->SetString("method", "spelling.feedback"); |
127 result->SetString("apiVersion", "v2"); | 128 result->SetString("apiVersion", api_version); |
128 return result; | 129 return result; |
129 } | 130 } |
130 | 131 |
131 // Returns true if the misspelling location is within text bounds. | 132 // Returns true if the misspelling location is within text bounds. |
132 bool IsInBounds(int misspelling_location, | 133 bool IsInBounds(int misspelling_location, |
133 int misspelling_length, | 134 int misspelling_length, |
134 size_t text_length) { | 135 size_t text_length) { |
135 return misspelling_location >= 0 && misspelling_length > 0 && | 136 return misspelling_location >= 0 && misspelling_length > 0 && |
136 static_cast<size_t>(misspelling_location) < text_length && | 137 static_cast<size_t>(misspelling_location) < text_length && |
137 static_cast<size_t>(misspelling_location + misspelling_length) <= | 138 static_cast<size_t>(misspelling_location + misspelling_length) <= |
138 text_length; | 139 text_length; |
139 } | 140 } |
140 | 141 |
142 // Returns the feedback API version. | |
143 std::string GetApiVersion() { | |
144 // This guard is temporary. | |
145 // TODO(rouslan): Remove the guard. http://crbug.com/247726 | |
146 if (base::FieldTrialList::FindFullName(kFeedbackFieldTrialName) == | |
147 kFeedbackFieldTrialEnabledGroupName && | |
148 CommandLine::ForCurrentProcess()->HasSwitch( | |
149 switches::kEnableSpellingServiceFeedback)) { | |
groby-ooo-7-16
2013/11/21 02:48:41
This confuses me, since we have a "FeedbackEnabled
please use gerrit instead
2013/11/22 22:06:31
The flag is to switch from "v2" to "v2-internal" A
please use gerrit instead
2013/11/22 22:14:22
--enable-spelling-feedback-field-trial.
| |
150 return "v2-internal"; | |
151 } | |
152 return "v2"; | |
153 } | |
154 | |
141 } // namespace | 155 } // namespace |
142 | 156 |
143 FeedbackSender::FeedbackSender(net::URLRequestContextGetter* request_context, | 157 FeedbackSender::FeedbackSender(net::URLRequestContextGetter* request_context, |
144 const std::string& language, | 158 const std::string& language, |
145 const std::string& country) | 159 const std::string& country) |
146 : request_context_(request_context), | 160 : request_context_(request_context), |
161 api_version_(GetApiVersion()), | |
147 language_(language), | 162 language_(language), |
148 country_(country), | 163 country_(country), |
149 misspelling_counter_(0), | 164 misspelling_counter_(0), |
150 session_start_(base::Time::Now()), | 165 session_start_(base::Time::Now()), |
151 feedback_service_url_(kFeedbackServiceURL) { | 166 feedback_service_url_(kFeedbackServiceURL) { |
152 // This guard is temporary. | |
153 // TODO(rouslan): Remove the guard. http://crbug.com/247726 | |
154 if (!CommandLine::ForCurrentProcess()->HasSwitch( | |
155 switches::kEnableSpellingServiceFeedback) || | |
156 base::FieldTrialList::FindFullName(kFeedbackFieldTrialName) != | |
157 kFeedbackFieldTrialEnabledGroupName) { | |
158 return; | |
159 } | |
160 | |
161 // The command-line switch is for testing and temporary. | 167 // The command-line switch is for testing and temporary. |
162 // TODO(rouslan): Remove the command-line switch when testing is complete. | 168 // TODO(rouslan): Remove the command-line switch when testing is complete. |
163 // http://crbug.com/247726 | 169 // http://crbug.com/247726 |
164 if (CommandLine::ForCurrentProcess()->HasSwitch( | 170 if (CommandLine::ForCurrentProcess()->HasSwitch( |
165 switches::kSpellingServiceFeedbackUrl)) { | 171 switches::kSpellingServiceFeedbackUrl)) { |
166 feedback_service_url_ = | 172 feedback_service_url_ = |
167 GURL(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 173 GURL(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
168 switches::kSpellingServiceFeedbackUrl)); | 174 switches::kSpellingServiceFeedbackUrl)); |
169 } | 175 } |
170 | |
171 int interval_seconds = chrome::spellcheck_common::kFeedbackIntervalSeconds; | |
172 // This command-line switch is for testing and temporary. | |
173 // TODO(rouslan): Remove the command-line switch when testing is complete. | |
174 // http://crbug.com/247726 | |
175 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
176 switches::kSpellingServiceFeedbackIntervalSeconds)) { | |
177 base::StringToInt(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
178 switches::kSpellingServiceFeedbackIntervalSeconds), | |
179 &interval_seconds); | |
180 if (interval_seconds < kMinIntervalSeconds) | |
181 interval_seconds = kMinIntervalSeconds; | |
182 } | |
183 | |
184 timer_.Start(FROM_HERE, | |
185 base::TimeDelta::FromSeconds(interval_seconds), | |
186 this, | |
187 &FeedbackSender::RequestDocumentMarkers); | |
188 } | 176 } |
189 | 177 |
190 FeedbackSender::~FeedbackSender() { | 178 FeedbackSender::~FeedbackSender() { |
191 } | 179 } |
192 | 180 |
193 void FeedbackSender::SelectedSuggestion(uint32 hash, int suggestion_index) { | 181 void FeedbackSender::SelectedSuggestion(uint32 hash, int suggestion_index) { |
194 Misspelling* misspelling = feedback_.GetMisspelling(hash); | 182 Misspelling* misspelling = feedback_.GetMisspelling(hash); |
195 // GetMisspelling() returns null for flushed feedback. Feedback is flushed | 183 // GetMisspelling() returns null for flushed feedback. Feedback is flushed |
196 // when the session expires every |kSessionHours| hours. | 184 // when the session expires every |kSessionHours| hours. |
197 if (!misspelling) | 185 if (!misspelling) |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
311 } | 299 } |
312 } | 300 } |
313 | 301 |
314 void FeedbackSender::OnLanguageCountryChange(const std::string& language, | 302 void FeedbackSender::OnLanguageCountryChange(const std::string& language, |
315 const std::string& country) { | 303 const std::string& country) { |
316 FlushFeedback(); | 304 FlushFeedback(); |
317 language_ = language; | 305 language_ = language; |
318 country_ = country; | 306 country_ = country; |
319 } | 307 } |
320 | 308 |
309 void FeedbackSender::StopFeedbackCollection() { | |
310 FlushFeedback(); | |
311 timer_.Stop(); | |
312 } | |
313 | |
314 void FeedbackSender::StartFeedbackCollection() { | |
315 int interval_seconds = chrome::spellcheck_common::kFeedbackIntervalSeconds; | |
316 // This command-line switch is for testing and temporary. | |
317 // TODO(rouslan): Remove the command-line switch when testing is complete. | |
318 // http://crbug.com/247726 | |
319 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
320 switches::kSpellingServiceFeedbackIntervalSeconds)) { | |
321 base::StringToInt(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
322 switches::kSpellingServiceFeedbackIntervalSeconds), | |
groby-ooo-7-16
2013/11/21 02:48:41
You might want to clamp to kMaxIntervalSeconds, to
please use gerrit instead
2013/11/22 22:06:31
Done.
| |
323 &interval_seconds); | |
324 if (interval_seconds < kMinIntervalSeconds) | |
325 interval_seconds = kMinIntervalSeconds; | |
326 } | |
327 timer_.Start(FROM_HERE, | |
groby-ooo-7-16
2013/11/21 02:48:41
I suppose timer automatically cancels pending task
please use gerrit instead
2013/11/22 22:06:31
Correct. Added a comment in feedback_sender.h.
| |
328 base::TimeDelta::FromSeconds(interval_seconds), | |
329 this, | |
330 &FeedbackSender::RequestDocumentMarkers); | |
331 } | |
332 | |
321 void FeedbackSender::OnURLFetchComplete(const net::URLFetcher* source) { | 333 void FeedbackSender::OnURLFetchComplete(const net::URLFetcher* source) { |
322 for (ScopedVector<net::URLFetcher>::iterator sender_it = senders_.begin(); | 334 for (ScopedVector<net::URLFetcher>::iterator sender_it = senders_.begin(); |
323 sender_it != senders_.end(); | 335 sender_it != senders_.end(); |
324 ++sender_it) { | 336 ++sender_it) { |
325 if (*sender_it == source) { | 337 if (*sender_it == source) { |
326 senders_.erase(sender_it); | 338 senders_.erase(sender_it); |
327 return; | 339 return; |
328 } | 340 } |
329 } | 341 } |
330 delete source; | 342 delete source; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
370 renderers_sent_feedback_.clear(); | 382 renderers_sent_feedback_.clear(); |
371 session_start_ = base::Time::Now(); | 383 session_start_ = base::Time::Now(); |
372 timer_.Reset(); | 384 timer_.Reset(); |
373 } | 385 } |
374 | 386 |
375 void FeedbackSender::SendFeedback(const std::vector<Misspelling>& feedback_data, | 387 void FeedbackSender::SendFeedback(const std::vector<Misspelling>& feedback_data, |
376 bool is_first_feedback_batch) { | 388 bool is_first_feedback_batch) { |
377 scoped_ptr<base::Value> feedback_value(BuildFeedbackValue( | 389 scoped_ptr<base::Value> feedback_value(BuildFeedbackValue( |
378 BuildParams(BuildSuggestionInfo(feedback_data, is_first_feedback_batch), | 390 BuildParams(BuildSuggestionInfo(feedback_data, is_first_feedback_batch), |
379 language_, | 391 language_, |
380 country_))); | 392 country_), |
393 api_version_)); | |
381 std::string feedback; | 394 std::string feedback; |
382 base::JSONWriter::Write(feedback_value.get(), &feedback); | 395 base::JSONWriter::Write(feedback_value.get(), &feedback); |
383 | 396 |
384 // The tests use this identifier to mock the URL fetcher. | 397 // The tests use this identifier to mock the URL fetcher. |
385 static const int kUrlFetcherId = 0; | 398 static const int kUrlFetcherId = 0; |
386 net::URLFetcher* sender = net::URLFetcher::Create( | 399 net::URLFetcher* sender = net::URLFetcher::Create( |
387 kUrlFetcherId, feedback_service_url_, net::URLFetcher::POST, this); | 400 kUrlFetcherId, feedback_service_url_, net::URLFetcher::POST, this); |
388 sender->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | 401 sender->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | |
389 net::LOAD_DO_NOT_SAVE_COOKIES); | 402 net::LOAD_DO_NOT_SAVE_COOKIES); |
390 sender->SetUploadData("application/json", feedback); | 403 sender->SetUploadData("application/json", feedback); |
391 senders_.push_back(sender); | 404 senders_.push_back(sender); |
392 | 405 |
393 // Request context is NULL in testing. | 406 // Request context is NULL in testing. |
394 if (request_context_.get()) { | 407 if (request_context_.get()) { |
395 sender->SetRequestContext(request_context_.get()); | 408 sender->SetRequestContext(request_context_.get()); |
396 sender->Start(); | 409 sender->Start(); |
397 } | 410 } |
398 } | 411 } |
399 | 412 |
400 } // namespace spellcheck | 413 } // namespace spellcheck |
OLD | NEW |