summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autocomplete
diff options
context:
space:
mode:
authormpearson@chromium.org <mpearson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-20 23:49:03 +0000
committermpearson@chromium.org <mpearson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-20 23:49:03 +0000
commit35d5560157d379015cd937816154368af1a0c602 (patch)
treef22422d1c76611c94d32715eb82c43252906ef23 /chrome/browser/autocomplete
parente6088be7a989ec3dd9ad29b8db12aaebf749a9ba (diff)
downloadchromium_src-35d5560157d379015cd937816154368af1a0c602.zip
chromium_src-35d5560157d379015cd937816154368af1a0c602.tar.gz
chromium_src-35d5560157d379015cd937816154368af1a0c602.tar.bz2
Omnibox: Log Elapsed Time Since Last Time The Default Match Changed
For users opted-in in UMA, in the logs that record interactions with the omnibox. keep track of the length of time the default match has been displayed. BUG= TEST=by hand, using LOG(INFO) Review URL: https://chromiumcodereview.appspot.com/11316057 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@168913 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/autocomplete')
-rw-r--r--chrome/browser/autocomplete/autocomplete_controller.cc93
-rw-r--r--chrome/browser/autocomplete/autocomplete_controller.h37
-rw-r--r--chrome/browser/autocomplete/autocomplete_log.cc3
-rw-r--r--chrome/browser/autocomplete/autocomplete_log.h6
4 files changed, 105 insertions, 34 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_controller.cc b/chrome/browser/autocomplete/autocomplete_controller.cc
index 9c2a406..e745381 100644
--- a/chrome/browser/autocomplete/autocomplete_controller.cc
+++ b/chrome/browser/autocomplete/autocomplete_controller.cc
@@ -213,7 +213,20 @@ void AutocompleteController::Start(
}
in_start_ = false;
CheckIfDone();
- UpdateResult(true);
+ // The second true forces saying the default match has changed.
+ // This triggers the edit model to update things such as the inline
+ // autocomplete state. In particular, if the user has typed a key
+ // since the last notification, and we're now re-running
+ // autocomplete, then we need to update the inline autocompletion
+ // even if the current match is for the same URL as the last run's
+ // default match. Likewise, the controller doesn't know what's
+ // happened in the edit since the last time it ran autocomplete.
+ // The user might have selected all the text and hit delete, then
+ // typed a new character. The selection and delete won't send any
+ // signals to the controller so it doesn't realize that anything was
+ // cleared or changed. Even if the default match hasn't changed, we
+ // need the edit model to update the display.
+ UpdateResult(false, true);
if (!done_)
StartExpireTimer();
@@ -263,13 +276,15 @@ void AutocompleteController::DeleteMatch(const AutocompleteMatch& match) {
}
void AutocompleteController::ExpireCopiedEntries() {
- // Clear out the results. This ensures no results from the previous result set
- // are copied over.
- result_.Reset();
- // We allow matches from the previous result set to starve out matches from
- // the new result set. This means in order to expire matches we have to query
- // the providers again.
- UpdateResult(false);
+ // The first true makes UpdateResult() clear out the results and
+ // regenerate them, thus ensuring that no results from the previous
+ // result set remain.
+ // The second true says to pretend the default match changed (even
+ // if it did not). This may not be necessary but the code has been
+ // like this for a long time and there's probably no great benefit in
+ // changing it. Classically we have erred on the side of notifying
+ // too often because it hasn't had any major side effects.
+ UpdateResult(true, true);
}
void AutocompleteController::OnProviderUpdate(bool updated_matches) {
@@ -285,7 +300,7 @@ void AutocompleteController::OnProviderUpdate(bool updated_matches) {
// Multiple providers may provide synchronous results, so we only update the
// results if we're not in Start().
if (!in_start_ && (updated_matches || done_))
- UpdateResult(false);
+ UpdateResult(false, false);
}
}
@@ -302,7 +317,23 @@ void AutocompleteController::AddProvidersInfo(
}
}
-void AutocompleteController::UpdateResult(bool is_synchronous_pass) {
+void AutocompleteController::UpdateResult(
+ bool regenerate_result,
+ bool force_notify_default_match_changed) {
+ const bool last_default_was_valid = result_.default_match() != result_.end();
+ // The following two variables are only set and used if
+ // |last_default_was_valid|.
+ string16 last_default_fill_into_edit, last_default_associated_keyword;
+ if (last_default_was_valid) {
+ last_default_fill_into_edit = result_.default_match()->fill_into_edit;
+ if (result_.default_match()->associated_keyword != NULL)
+ last_default_associated_keyword =
+ result_.default_match()->associated_keyword->keyword;
+ }
+
+ if (regenerate_result)
+ result_.Reset();
+
AutocompleteResult last_result;
last_result.Swap(&result_);
@@ -329,27 +360,29 @@ void AutocompleteController::UpdateResult(bool is_synchronous_pass) {
UpdateAssociatedKeywords(&result_);
UpdateAssistedQueryStats(&result_);
- bool notify_default_match = is_synchronous_pass;
- if (!is_synchronous_pass) {
- const bool last_default_was_valid =
- last_result.default_match() != last_result.end();
- const bool default_is_valid = result_.default_match() != result_.end();
- // We've gotten async results. Send notification that the default match
- // updated if fill_into_edit differs or associated_keyword differ. (The
- // latter can change if we've just started Chrome and the keyword database
- // finishes loading while processing this request.) We don't check the URL
- // as that may change for the default match even though the fill into edit
- // hasn't changed (see SearchProvider for one case of this).
- notify_default_match =
- (last_default_was_valid != default_is_valid) ||
- (default_is_valid &&
- ((result_.default_match()->fill_into_edit !=
- last_result.default_match()->fill_into_edit) ||
- (result_.default_match()->associated_keyword.get() !=
- last_result.default_match()->associated_keyword.get())));
+ const bool default_is_valid = result_.default_match() != result_.end();
+ string16 default_associated_keyword;
+ if (default_is_valid &&
+ (result_.default_match()->associated_keyword != NULL)) {
+ default_associated_keyword =
+ result_.default_match()->associated_keyword->keyword;
}
-
- NotifyChanged(notify_default_match);
+ // We've gotten async results. Send notification that the default match
+ // updated if fill_into_edit differs or associated_keyword differ. (The
+ // latter can change if we've just started Chrome and the keyword database
+ // finishes loading while processing this request.) We don't check the URL
+ // as that may change for the default match even though the fill into edit
+ // hasn't changed (see SearchProvider for one case of this).
+ const bool notify_default_match =
+ (last_default_was_valid != default_is_valid) ||
+ (last_default_was_valid &&
+ ((result_.default_match()->fill_into_edit !=
+ last_default_fill_into_edit) ||
+ (default_associated_keyword != last_default_associated_keyword)));
+ if (notify_default_match)
+ last_time_default_match_changed_ = base::TimeTicks::Now();
+
+ NotifyChanged(force_notify_default_match_changed || notify_default_match);
}
void AutocompleteController::UpdateAssociatedKeywords(
diff --git a/chrome/browser/autocomplete/autocomplete_controller.h b/chrome/browser/autocomplete/autocomplete_controller.h
index d0466c7..2339c70 100644
--- a/chrome/browser/autocomplete/autocomplete_controller.h
+++ b/chrome/browser/autocomplete/autocomplete_controller.h
@@ -9,6 +9,7 @@
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/string16.h"
+#include "base/time.h"
#include "base/timer.h"
#include "chrome/browser/autocomplete/autocomplete_input.h"
#include "chrome/browser/autocomplete/autocomplete_provider.h"
@@ -125,6 +126,10 @@ class AutocompleteController : public AutocompleteProviderListener {
bool done() const { return done_; }
const ACProviders* providers() const { return &providers_; }
+ const base::TimeTicks& last_time_default_match_changed() const {
+ return last_time_default_match_changed_;
+ }
+
// AutocompleteProviderListener:
virtual void OnProviderUpdate(bool updated_matches) OVERRIDE;
@@ -142,10 +147,22 @@ class AutocompleteController : public AutocompleteProviderListener {
RedundantKeywordsIgnoredInResult);
FRIEND_TEST_ALL_PREFIXES(AutocompleteProviderTest, UpdateAssistedQueryStats);
- // Updates |result_| to reflect the current provider state. Resets timers and
- // fires notifications as necessary. |is_synchronous_pass| is true only when
- // Start() is calling this to get the synchronous result.
- void UpdateResult(bool is_synchronous_pass);
+ // Updates |result_| to reflect the current provider state and fires
+ // notifications. If |regenerate_result| then we clear the result
+ // so when we incorporate the current provider state we end up
+ // implicitly removing all expired matches. (Normally we allow
+ // matches from the previous result set carry over. These stale
+ // results may outrank legitimate matches from the current result
+ // set. Sometimes we just want the current matches; the easier way
+ // to do this is to throw everything out and reconstruct the result
+ // set from the providers' current data.)
+ // If |force_notify_default_match_changed|, we tell NotifyChanged
+ // the default match has changed even if it hasn't. This is
+ // necessary in some cases; for instance, if the user typed a new
+ // character, the edit model needs to repaint (highlighting changed)
+ // even if the default match didn't change.
+ void UpdateResult(bool regenerate_result,
+ bool force_notify_default_match_changed);
// Updates |result| to populate each match's |associated_keyword| if that
// match can show a keyword hint. |result| should be sorted by
@@ -188,6 +205,18 @@ class AutocompleteController : public AutocompleteProviderListener {
// Data from the autocomplete query.
AutocompleteResult result_;
+ // The most recent time the default match (inline match) changed. This may
+ // be earlier than the most recent keystroke if the recent keystrokes didn't
+ // change the suggested match in the omnibox. (For instance, if
+ // a user typed "mail.goog" and the match https://mail.google.com/ was
+ // the destination match ever since the user typed "ma" then this is
+ // the time that URL first appeared as the default match.) This may
+ // also be more recent than the last keystroke if there was an
+ // asynchronous provider that returned and changed the default
+ // match. See UpdateResult() for details on when we consider a
+ // match to have changed.
+ base::TimeTicks last_time_default_match_changed_;
+
// Timer used to remove any matches copied from the last result. When run
// invokes |ExpireCopiedEntries|.
base::OneShotTimer<AutocompleteController> expire_timer_;
diff --git a/chrome/browser/autocomplete/autocomplete_log.cc b/chrome/browser/autocomplete/autocomplete_log.cc
index 77023c0..7d6f1e6 100644
--- a/chrome/browser/autocomplete/autocomplete_log.cc
+++ b/chrome/browser/autocomplete/autocomplete_log.cc
@@ -13,6 +13,7 @@ AutocompleteLog::AutocompleteLog(
metrics::OmniboxEventProto::PageClassification current_page_classification,
base::TimeDelta elapsed_time_since_user_first_modified_omnibox,
size_t inline_autocompleted_length,
+ base::TimeDelta elapsed_time_since_last_change_to_default_match,
const AutocompleteResult& result)
: text(text),
just_deleted_text(just_deleted_text),
@@ -23,6 +24,8 @@ AutocompleteLog::AutocompleteLog(
elapsed_time_since_user_first_modified_omnibox(
elapsed_time_since_user_first_modified_omnibox),
inline_autocompleted_length(inline_autocompleted_length),
+ elapsed_time_since_last_change_to_default_match(
+ elapsed_time_since_last_change_to_default_match),
result(result),
providers_info() {
}
diff --git a/chrome/browser/autocomplete/autocomplete_log.h b/chrome/browser/autocomplete/autocomplete_log.h
index 245481b..2782eef 100644
--- a/chrome/browser/autocomplete/autocomplete_log.h
+++ b/chrome/browser/autocomplete/autocomplete_log.h
@@ -29,6 +29,7 @@ struct AutocompleteLog {
current_page_classification,
base::TimeDelta elapsed_time_since_user_first_modified_omnibox,
size_t inline_autocompleted_length,
+ base::TimeDelta elapsed_time_since_last_change_to_default_match,
const AutocompleteResult& result);
~AutocompleteLog();
@@ -67,6 +68,11 @@ struct AutocompleteLog {
// if not available.
size_t inline_autocompleted_length;
+ // The amount of time since the last time the default (i.e., inline)
+ // match changed. This will certainly be less than
+ // elapsed_time_since_user_first_modified_omnibox.
+ base::TimeDelta elapsed_time_since_last_change_to_default_match;
+
// Result set.
const AutocompleteResult& result;