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

Unified Diff: chrome/browser/ui/webui/history_ui.cc

Issue 12381081: History: Add UMA collection for full history sync. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase. Created 7 years, 9 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/ui/webui/history_ui.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/webui/history_ui.cc
diff --git a/chrome/browser/ui/webui/history_ui.cc b/chrome/browser/ui/webui/history_ui.cc
index 3a22dca070fb3f906e7dd8eec9788b3411b6e1b7..dd2f2c6591bbb76d13895f8bae815786e36c01fb 100644
--- a/chrome/browser/ui/webui/history_ui.cc
+++ b/chrome/browser/ui/webui/history_ui.cc
@@ -13,6 +13,7 @@
#include "base/i18n/time_formatting.h"
#include "base/memory/singleton.h"
#include "base/message_loop.h"
+#include "base/metrics/histogram.h"
#include "base/string16.h"
#include "base/string_piece.h"
#include "base/strings/string_number_conversions.h"
@@ -75,6 +76,14 @@ static const int kWebHistoryTimeoutSeconds = 3;
namespace {
+// Buckets for UMA histograms.
+enum WebHistoryQueryBuckets {
+ WEB_HISTORY_QUERY_FAILED = 0,
+ WEB_HISTORY_QUERY_SUCCEEDED,
+ WEB_HISTORY_QUERY_TIMED_OUT,
+ NUM_WEB_HISTORY_QUERY_BUCKETS
+};
+
#if defined(OS_MACOSX)
const char kIncognitoModeShortcut[] = "("
"\xE2\x87\xA7" // Shift symbol (U+21E7 'UPWARDS WHITE ARROW').
@@ -189,6 +198,26 @@ bool GetResultTimeAndUrl(Value* result, base::Time* time, string16* url) {
return false;
}
+// Removes all entries in |entry_list| that are older than the |cutoff|.
+// |entry_list| must already be sorted in reverse chronological order.
+void RemoveOlderEntries(
+ std::vector<BrowsingHistoryHandler::HistoryEntry>* entry_list,
+ base::Time cutoff) {
+ for (std::vector<BrowsingHistoryHandler::HistoryEntry>::iterator it =
+ entry_list->begin(); it != entry_list->end(); ++it) {
+ if (it->time < cutoff) {
+ entry_list->erase(it, entry_list->end());
+ break;
+ }
+ }
+}
+
+// Returns true if |entry| represents a local visit that had no corresponding
+// visit on the server.
+bool IsLocalOnlyResult(const BrowsingHistoryHandler::HistoryEntry& entry) {
+ return entry.entry_type == BrowsingHistoryHandler::HistoryEntry::LOCAL_ENTRY;
+}
+
} // namespace
////////////////////////////////////////////////////////////////////////////////
@@ -198,9 +227,12 @@ bool GetResultTimeAndUrl(Value* result, base::Time* time, string16* url) {
////////////////////////////////////////////////////////////////////////////////
BrowsingHistoryHandler::HistoryEntry::HistoryEntry(
+ BrowsingHistoryHandler::HistoryEntry::EntryType entry_type,
const GURL& url, const string16& title, base::Time time,
- const std::set<int64>& timestamps, bool is_search_result,
- const string16& snippet) : all_timestamps(timestamps) {
+ const std::set<int64>& timestamps,
+ bool is_search_result, const string16& snippet)
+ : all_timestamps(timestamps) {
+ this->entry_type = entry_type;
this->url = url;
this->title = title;
this->time = time;
@@ -216,7 +248,7 @@ BrowsingHistoryHandler::HistoryEntry::~HistoryEntry() {
}
void BrowsingHistoryHandler::HistoryEntry::SetUrlAndTitle(
- DictionaryValue* result) {
+ DictionaryValue* result) const {
result->SetString("url", url.spec());
bool using_url_as_the_title = false;
@@ -240,7 +272,8 @@ void BrowsingHistoryHandler::HistoryEntry::SetUrlAndTitle(
}
scoped_ptr<DictionaryValue> BrowsingHistoryHandler::HistoryEntry::ToValue(
- BookmarkModel* bookmark_model, ManagedUserService* managed_user_service) {
+ BookmarkModel* bookmark_model,
+ ManagedUserService* managed_user_service) const {
scoped_ptr<DictionaryValue> result(new DictionaryValue());
SetUrlAndTitle(result.get());
result->SetDouble("time", time.ToJsTime());
@@ -367,7 +400,11 @@ bool BrowsingHistoryHandler::ExtractIntegerValueAtIndex(const ListValue* value,
void BrowsingHistoryHandler::WebHistoryTimeout() {
// TODO(dubroy): Communicate the failure to the front end.
if (!results_info_value_.empty())
- ReturnResultsToFrontEnd(false, 0);
+ ReturnResultsToFrontEnd();
+
+ UMA_HISTOGRAM_ENUMERATION(
+ "WebHistory.QueryCompletion",
+ WEB_HISTORY_QUERY_TIMED_OUT, NUM_WEB_HISTORY_QUERY_BUCKETS);
}
void BrowsingHistoryHandler::QueryHistory(
@@ -392,11 +429,14 @@ void BrowsingHistoryHandler::QueryHistory(
history::WebHistoryService* web_history =
WebHistoryServiceFactory::GetForProfile(profile);
if (web_history) {
+ web_history_query_results_.clear();
web_history_request_ = web_history->QueryHistory(
search_text,
options,
base::Bind(&BrowsingHistoryHandler::WebHistoryQueryComplete,
- base::Unretained(this), search_text, options));
+ base::Unretained(this),
+ search_text, options,
+ base::TimeTicks::Now()));
// Start a timer so we know when to give up.
web_history_timer_.Start(
FROM_HERE, base::TimeDelta::FromSeconds(kWebHistoryTimeoutSeconds),
@@ -747,15 +787,21 @@ void BrowsingHistoryHandler::RemoveDuplicateResults(
new_results.push_back(*it);
} else {
// Keep track of the timestamps of all visits to the URL on the same day.
- current_day_entries[it->url].all_timestamps.insert(
+ BrowsingHistoryHandler::HistoryEntry* entry =
+ &current_day_entries[it->url];
+ entry->all_timestamps.insert(
it->all_timestamps.begin(), it->all_timestamps.end());
+
+ if (entry->entry_type != it->entry_type) {
+ entry->entry_type =
+ BrowsingHistoryHandler::HistoryEntry::COMBINED_ENTRY;
+ }
}
}
results->swap(new_results);
}
-void BrowsingHistoryHandler::ReturnResultsToFrontEnd(
- bool results_need_merge, int max_count) {
+void BrowsingHistoryHandler::ReturnResultsToFrontEnd() {
Profile* profile = Profile::FromWebUI(web_ui());
BookmarkModel* bookmark_model = BookmarkModelFactory::GetForProfile(profile);
ManagedUserService* managed_user_service = NULL;
@@ -763,16 +809,39 @@ void BrowsingHistoryHandler::ReturnResultsToFrontEnd(
managed_user_service = ManagedUserServiceFactory::GetForProfile(profile);
#endif
- if (results_need_merge)
+ // Combine the local and remote results into |query_results_|, and remove
+ // any duplicates.
+ if (query_results_.size() && web_history_query_results_.size()) {
+ // Each result set covers a particular time range. Determine the
+ // intersection of the two time ranges, discard any entries from either
+ // set the are older than that, and then combine the results.
+ base::Time cutoff_time = std::max(query_results_.back().time,
+ web_history_query_results_.back().time);
+ RemoveOlderEntries(&query_results_, cutoff_time);
+ RemoveOlderEntries(&web_history_query_results_, cutoff_time);
+
+ int local_result_count = query_results_.size();
+ query_results_.insert(query_results_.end(),
+ web_history_query_results_.begin(),
+ web_history_query_results_.end());
RemoveDuplicateResults(&query_results_);
- // Convert the result vector into a ListValue with at most |max_count|
- // elements.
+ // In the best case, we expect that all local results are duplicated on the
+ // server. Keep track of how many are missing.
+ if (local_result_count) {
+ int missing_count = std::count_if(
+ query_results_.begin(), query_results_.end(), IsLocalOnlyResult);
+ UMA_HISTOGRAM_PERCENTAGE("WebHistory.LocalResultMissingOnServer",
+ missing_count * 100.0 / local_result_count);
+ }
+ }
+
+ // Convert the result vector into a ListValue.
ListValue results_value;
- int query_results_size = static_cast<int>(query_results_.size());
- for (int i = 0; i < query_results_size && i < max_count; ++i) {
+ for (std::vector<BrowsingHistoryHandler::HistoryEntry>::iterator it =
+ query_results_.begin(); it != query_results_.end(); ++it) {
scoped_ptr<base::Value> value(
- query_results_[i].ToValue(bookmark_model, managed_user_service));
+ it->ToValue(bookmark_model, managed_user_service));
results_value.Append(value.release());
}
@@ -780,6 +849,7 @@ void BrowsingHistoryHandler::ReturnResultsToFrontEnd(
"historyResult", results_info_value_, results_value);
results_info_value_.Clear();
query_results_.clear();
+ web_history_query_results_.clear();
}
void BrowsingHistoryHandler::QueryComplete(
@@ -787,8 +857,8 @@ void BrowsingHistoryHandler::QueryComplete(
const history::QueryOptions& options,
HistoryService::Handle request_handle,
history::QueryResults* results) {
- // If we're appending to existing results, they will need merging.
- bool needs_merge = query_results_.size() > 0;
+ DCHECK_EQ(0U, query_results_.size());
+ query_results_.reserve(results->size());
for (size_t i = 0; i < results->size(); ++i) {
history::URLResult const &page = (*results)[i];
@@ -797,12 +867,14 @@ void BrowsingHistoryHandler::QueryComplete(
timestamps.insert(page.visit_time().ToInternalValue());
query_results_.push_back(
- HistoryEntry(page.url(),
- page.title(),
- page.visit_time(),
- timestamps,
- !search_text.empty(),
- page.snippet().text()));
+ HistoryEntry(
+ HistoryEntry::LOCAL_ENTRY,
+ page.url(),
+ page.title(),
+ page.visit_time(),
+ timestamps,
+ !search_text.empty(),
+ page.snippet().text()));
}
results_info_value_.SetString("term", search_text);
@@ -821,18 +893,33 @@ void BrowsingHistoryHandler::QueryComplete(
getRelativeDateLocalized(base::Time::Now()));
}
if (!web_history_timer_.IsRunning())
- ReturnResultsToFrontEnd(needs_merge, options.max_count);
+ ReturnResultsToFrontEnd();
}
void BrowsingHistoryHandler::WebHistoryQueryComplete(
const string16& search_text,
const history::QueryOptions& options,
+ base::TimeTicks start_time,
history::WebHistoryService::Request* request,
const DictionaryValue* results_value) {
+ base::TimeDelta delta = base::TimeTicks::Now() - start_time;
+ UMA_HISTOGRAM_TIMES("WebHistory.ResponseTime", delta);
+
+ // If the response came in too late, do nothing.
+ // TODO(dubroy): Maybe show a banner, and prompt the user to reload?
+ if (!web_history_timer_.IsRunning())
+ return;
web_history_timer_.Stop();
+ UMA_HISTOGRAM_ENUMERATION(
+ "WebHistory.QueryCompletion",
+ results_value ? WEB_HISTORY_QUERY_SUCCEEDED : WEB_HISTORY_QUERY_FAILED,
+ NUM_WEB_HISTORY_QUERY_BUCKETS);
+
+ DCHECK_EQ(0U, web_history_query_results_.size());
const ListValue* events = NULL;
if (results_value && results_value->GetList("event", &events)) {
+ web_history_query_results_.reserve(events->GetSize());
for (unsigned int i = 0; i < events->GetSize(); ++i) {
const DictionaryValue* event = NULL;
const DictionaryValue* result = NULL;
@@ -880,8 +967,9 @@ void BrowsingHistoryHandler::WebHistoryQueryComplete(
visit_time = time;
}
GURL gurl(url);
- query_results_.push_back(
+ web_history_query_results_.push_back(
HistoryEntry(
+ HistoryEntry::REMOTE_ENTRY,
gurl,
title,
visit_time,
@@ -893,7 +981,7 @@ void BrowsingHistoryHandler::WebHistoryQueryComplete(
NOTREACHED() << "Failed to parse JSON response.";
}
if (!results_info_value_.empty())
- ReturnResultsToFrontEnd(true, options.max_count);
+ ReturnResultsToFrontEnd();
}
void BrowsingHistoryHandler::RemoveComplete() {
« no previous file with comments | « chrome/browser/ui/webui/history_ui.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698