Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(311)

Side by Side Diff: chrome/browser/autocomplete/autocomplete_controller.cc

Issue 11316057: Omnibox: Log Elapsed Time Since Last Time The Default Match Changed (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/autocomplete/autocomplete_controller.h" 5 #include "chrome/browser/autocomplete/autocomplete_controller.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 if (matches_requested == AutocompleteInput::ALL_MATCHES && 206 if (matches_requested == AutocompleteInput::ALL_MATCHES &&
207 (text.length() < 6)) { 207 (text.length() < 6)) {
208 base::TimeTicks end_time = base::TimeTicks::Now(); 208 base::TimeTicks end_time = base::TimeTicks::Now();
209 std::string name = "Omnibox.QueryTime." + base::IntToString(text.length()); 209 std::string name = "Omnibox.QueryTime." + base::IntToString(text.length());
210 base::Histogram* counter = base::Histogram::FactoryGet( 210 base::Histogram* counter = base::Histogram::FactoryGet(
211 name, 1, 1000, 50, base::Histogram::kUmaTargetedHistogramFlag); 211 name, 1, 1000, 50, base::Histogram::kUmaTargetedHistogramFlag);
212 counter->Add(static_cast<int>((end_time - start_time).InMilliseconds())); 212 counter->Add(static_cast<int>((end_time - start_time).InMilliseconds()));
213 } 213 }
214 in_start_ = false; 214 in_start_ = false;
215 CheckIfDone(); 215 CheckIfDone();
216 UpdateResult(true); 216 // The second true forces saying the default match has changed.
217 // This triggers the edit model to update things such as the inline
218 // autocomplete state. In particular, if the user has typed a key
219 // since the last notification, and we're now re-running
220 // autocomplete, then we need to update the inline autocompletion
221 // even if the current match is for the same URL as the last run's
222 // default match. Likewise, the controller doesn't know what's
223 // happened in the edit since the last time it ran autocomplete.
224 // The user might have selected all the text and hit delete, then
225 // typed a new character. The selection and delete won't send any
226 // signals to the controller so it doesn't realize that anything was
227 // cleared or changed. Even if the default match hasn't changed, we
228 // need the edit model to update the display.
229 UpdateResult(false, true);
217 230
218 if (!done_) 231 if (!done_)
219 StartExpireTimer(); 232 StartExpireTimer();
220 } 233 }
221 234
222 void AutocompleteController::Stop(bool clear_result) { 235 void AutocompleteController::Stop(bool clear_result) {
223 for (ACProviders::const_iterator i(providers_.begin()); i != providers_.end(); 236 for (ACProviders::const_iterator i(providers_.begin()); i != providers_.end();
224 ++i) { 237 ++i) {
225 (*i)->Stop(clear_result); 238 (*i)->Stop(clear_result);
226 } 239 }
(...skipping 29 matching lines...) Expand all
256 DCHECK(match.deletable); 269 DCHECK(match.deletable);
257 match.provider->DeleteMatch(match); // This may synchronously call back to 270 match.provider->DeleteMatch(match); // This may synchronously call back to
258 // OnProviderUpdate(). 271 // OnProviderUpdate().
259 // If DeleteMatch resulted in a callback to OnProviderUpdate and we're 272 // If DeleteMatch resulted in a callback to OnProviderUpdate and we're
260 // not done, we might attempt to redisplay the deleted match. Make sure 273 // not done, we might attempt to redisplay the deleted match. Make sure
261 // we aren't displaying it by removing any old entries. 274 // we aren't displaying it by removing any old entries.
262 ExpireCopiedEntries(); 275 ExpireCopiedEntries();
263 } 276 }
264 277
265 void AutocompleteController::ExpireCopiedEntries() { 278 void AutocompleteController::ExpireCopiedEntries() {
266 // Clear out the results. This ensures no results from the previous result set 279 // The first true makes UpdateResult() clear out the results and
267 // are copied over. 280 // regenerate them, thus ensuring that no results from the previous
268 result_.Reset(); 281 // result set remain.
269 // We allow matches from the previous result set to starve out matches from 282 // The second true says to pretend the default match changed (even
270 // the new result set. This means in order to expire matches we have to query 283 // if it did not). This may not be necessary but the code has been
271 // the providers again. 284 // like this for a long time and there's probably no great benefit in
272 UpdateResult(false); 285 // changing it. Classically we have erred on the side of notifying
286 // too often because it hasn't had any major side effects.
287 UpdateResult(true, true);
273 } 288 }
274 289
275 void AutocompleteController::OnProviderUpdate(bool updated_matches) { 290 void AutocompleteController::OnProviderUpdate(bool updated_matches) {
276 if (in_zero_suggest_) { 291 if (in_zero_suggest_) {
277 // We got ZeroSuggest results before Start(). Show only those results, 292 // We got ZeroSuggest results before Start(). Show only those results,
278 // because results from other providers are stale. 293 // because results from other providers are stale.
279 result_.Reset(); 294 result_.Reset();
280 result_.AppendMatches(zero_suggest_provider_->matches()); 295 result_.AppendMatches(zero_suggest_provider_->matches());
281 result_.SortAndCull(input_, profile_); 296 result_.SortAndCull(input_, profile_);
282 NotifyChanged(true); 297 NotifyChanged(true);
283 } else { 298 } else {
284 CheckIfDone(); 299 CheckIfDone();
285 // Multiple providers may provide synchronous results, so we only update the 300 // Multiple providers may provide synchronous results, so we only update the
286 // results if we're not in Start(). 301 // results if we're not in Start().
287 if (!in_start_ && (updated_matches || done_)) 302 if (!in_start_ && (updated_matches || done_))
288 UpdateResult(false); 303 UpdateResult(false, false);
289 } 304 }
290 } 305 }
291 306
292 void AutocompleteController::AddProvidersInfo( 307 void AutocompleteController::AddProvidersInfo(
293 ProvidersInfo* provider_info) const { 308 ProvidersInfo* provider_info) const {
294 provider_info->clear(); 309 provider_info->clear();
295 for (ACProviders::const_iterator i(providers_.begin()); i != providers_.end(); 310 for (ACProviders::const_iterator i(providers_.begin()); i != providers_.end();
296 ++i) { 311 ++i) {
297 // Add per-provider info, if any. 312 // Add per-provider info, if any.
298 (*i)->AddProviderInfo(provider_info); 313 (*i)->AddProviderInfo(provider_info);
299 314
300 // This is also a good place to put code to add info that you want to 315 // This is also a good place to put code to add info that you want to
301 // add for every provider. 316 // add for every provider.
302 } 317 }
303 } 318 }
304 319
305 void AutocompleteController::UpdateResult(bool is_synchronous_pass) { 320 void AutocompleteController::UpdateResult(
321 bool regenerate_result,
322 bool force_notify_default_match_changed) {
323 const bool last_default_was_valid = result_.default_match() != result_.end();
324 // The following two variables are only set and used if
325 // |last_default_was_valid|.
326 string16 last_default_fill_into_edit, last_default_associated_keyword;
327 if (last_default_was_valid) {
328 last_default_fill_into_edit = result_.default_match()->fill_into_edit;
329 if (result_.default_match()->associated_keyword != NULL)
330 last_default_associated_keyword =
331 result_.default_match()->associated_keyword->keyword;
332 }
333
334 if (regenerate_result)
335 result_.Reset();
336
306 AutocompleteResult last_result; 337 AutocompleteResult last_result;
307 last_result.Swap(&result_); 338 last_result.Swap(&result_);
308 339
309 for (ACProviders::const_iterator i(providers_.begin()); i != providers_.end(); 340 for (ACProviders::const_iterator i(providers_.begin()); i != providers_.end();
310 ++i) 341 ++i)
311 result_.AppendMatches((*i)->matches()); 342 result_.AppendMatches((*i)->matches());
312 343
313 // Sort the matches and trim to a small number of "best" matches. 344 // Sort the matches and trim to a small number of "best" matches.
314 result_.SortAndCull(input_, profile_); 345 result_.SortAndCull(input_, profile_);
315 346
316 // Need to validate before invoking CopyOldMatches as the old matches are not 347 // Need to validate before invoking CopyOldMatches as the old matches are not
317 // valid against the current input. 348 // valid against the current input.
318 #ifndef NDEBUG 349 #ifndef NDEBUG
319 result_.Validate(); 350 result_.Validate();
320 #endif 351 #endif
321 352
322 if (!done_) { 353 if (!done_) {
323 // This conditional needs to match the conditional in Start that invokes 354 // This conditional needs to match the conditional in Start that invokes
324 // StartExpireTimer. 355 // StartExpireTimer.
325 result_.CopyOldMatches(input_, last_result, profile_); 356 result_.CopyOldMatches(input_, last_result, profile_);
326 } 357 }
327 358
328 UpdateKeywordDescriptions(&result_); 359 UpdateKeywordDescriptions(&result_);
329 UpdateAssociatedKeywords(&result_); 360 UpdateAssociatedKeywords(&result_);
330 UpdateAssistedQueryStats(&result_); 361 UpdateAssistedQueryStats(&result_);
331 362
332 bool notify_default_match = is_synchronous_pass; 363 const bool default_is_valid = result_.default_match() != result_.end();
333 if (!is_synchronous_pass) { 364 string16 default_associated_keyword;
334 const bool last_default_was_valid = 365 if (default_is_valid &&
335 last_result.default_match() != last_result.end(); 366 (result_.default_match()->associated_keyword != NULL)) {
336 const bool default_is_valid = result_.default_match() != result_.end(); 367 default_associated_keyword =
337 // We've gotten async results. Send notification that the default match 368 result_.default_match()->associated_keyword->keyword;
338 // updated if fill_into_edit differs or associated_keyword differ. (The
339 // latter can change if we've just started Chrome and the keyword database
340 // finishes loading while processing this request.) We don't check the URL
341 // as that may change for the default match even though the fill into edit
342 // hasn't changed (see SearchProvider for one case of this).
343 notify_default_match =
344 (last_default_was_valid != default_is_valid) ||
345 (default_is_valid &&
346 ((result_.default_match()->fill_into_edit !=
347 last_result.default_match()->fill_into_edit) ||
348 (result_.default_match()->associated_keyword.get() !=
349 last_result.default_match()->associated_keyword.get())));
350 } 369 }
370 // We've gotten async results. Send notification that the default match
371 // updated if fill_into_edit differs or associated_keyword differ. (The
372 // latter can change if we've just started Chrome and the keyword database
373 // finishes loading while processing this request.) We don't check the URL
374 // as that may change for the default match even though the fill into edit
375 // hasn't changed (see SearchProvider for one case of this).
376 const bool notify_default_match =
377 (last_default_was_valid != default_is_valid) ||
378 (last_default_was_valid &&
379 ((result_.default_match()->fill_into_edit !=
380 last_default_fill_into_edit) ||
381 (default_associated_keyword != last_default_associated_keyword)));
382 if (notify_default_match)
383 last_time_default_match_changed_ = base::TimeTicks::Now();
351 384
352 NotifyChanged(notify_default_match); 385 NotifyChanged(force_notify_default_match_changed || notify_default_match);
353 } 386 }
354 387
355 void AutocompleteController::UpdateAssociatedKeywords( 388 void AutocompleteController::UpdateAssociatedKeywords(
356 AutocompleteResult* result) { 389 AutocompleteResult* result) {
357 if (!keyword_provider_) 390 if (!keyword_provider_)
358 return; 391 return;
359 392
360 std::set<string16> keywords; 393 std::set<string16> keywords;
361 for (ACMatches::iterator match(result->begin()); match != result->end(); 394 for (ACMatches::iterator match(result->begin()); match != result->end();
362 ++match) { 395 ++match) {
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 } 504 }
472 done_ = true; 505 done_ = true;
473 } 506 }
474 507
475 void AutocompleteController::StartExpireTimer() { 508 void AutocompleteController::StartExpireTimer() {
476 if (result_.HasCopiedMatches()) 509 if (result_.HasCopiedMatches())
477 expire_timer_.Start(FROM_HERE, 510 expire_timer_.Start(FROM_HERE,
478 base::TimeDelta::FromMilliseconds(kExpireTimeMS), 511 base::TimeDelta::FromMilliseconds(kExpireTimeMS),
479 this, &AutocompleteController::ExpireCopiedEntries); 512 this, &AutocompleteController::ExpireCopiedEntries);
480 } 513 }
OLDNEW
« no previous file with comments | « chrome/browser/autocomplete/autocomplete_controller.h ('k') | chrome/browser/autocomplete/autocomplete_log.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698