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

Unified Diff: chrome/browser/extensions/extension_webrequest_time_tracker.cc

Issue 8176001: Warn user in case extension delays network traffic too much. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Merged with ToT Created 9 years, 2 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
Index: chrome/browser/extensions/extension_webrequest_time_tracker.cc
diff --git a/chrome/browser/extensions/extension_webrequest_time_tracker.cc b/chrome/browser/extensions/extension_webrequest_time_tracker.cc
index 9ccdef7387e43ae3668d033c8343aaddba75e9a5..abae50106c92ff31bb7b02b29498c3cb2b61a8bc 100644
--- a/chrome/browser/extensions/extension_webrequest_time_tracker.cc
+++ b/chrome/browser/extensions/extension_webrequest_time_tracker.cc
@@ -4,7 +4,13 @@
#include "chrome/browser/extensions/extension_webrequest_time_tracker.h"
+#include "base/bind.h"
+#include "base/compiler_specific.h"
#include "base/metrics/histogram.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_warning_set.h"
+#include "chrome/browser/profiles/profile_manager.h"
// TODO(mpcomplete): tweak all these constants.
namespace {
@@ -25,23 +31,86 @@ const double kThresholdExcessiveDelay = 0.50;
// delay, then we will warn the user.
const size_t kNumModerateDelaysBeforeWarning = 50u;
const size_t kNumExcessiveDelaysBeforeWarning = 10u;
+
+// Handles ExtensionWebRequestTimeTrackerDelegate calls on UI thread.
+void NotifyNetworkDelaysOnUI(void* profile,
+ std::set<std::string> extension_ids) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ Profile* p = reinterpret_cast<Profile*>(profile);
+ if (!p || !g_browser_process->profile_manager()->IsValidProfile(p))
+ return;
+
+ ExtensionWarningSet* warnings =
+ p->GetExtensionService()->extension_warnings();
+
+ for (std::set<std::string>::const_iterator i = extension_ids.begin();
+ i != extension_ids.end(); ++i) {
+ warnings->SetWarning(ExtensionWarningSet::kNetworkDelay, *i);
+ }
+}
+
+// Default implementation for ExtensionWebRequestTimeTrackerDelegate
+// that sets a warning in the extension service of |profile|.
+class DefaultDelegate : public ExtensionWebRequestTimeTrackerDelegate {
+ public:
+ virtual ~DefaultDelegate() {}
+
+ // Implementation of ExtensionWebRequestTimeTrackerDelegate.
+ virtual void NotifyExcessiveDelays(
+ void* profile,
+ size_t num_delayed_messages,
+ size_t total_num_messages,
+ const std::set<std::string>& extension_ids) OVERRIDE;
+ virtual void NotifyModerateDelays(
+ void* profile,
+ size_t num_delayed_messages,
+ size_t total_num_messages,
+ const std::set<std::string>& extension_ids) OVERRIDE;
+};
+
+void DefaultDelegate::NotifyExcessiveDelays(
+ void* profile,
+ size_t num_delayed_messages,
+ size_t total_num_messages,
+ const std::set<std::string>& extension_ids) {
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&NotifyNetworkDelaysOnUI, profile, extension_ids));
+}
+
+void DefaultDelegate::NotifyModerateDelays(
+ void* profile,
+ size_t num_delayed_messages,
+ size_t total_num_messages,
+ const std::set<std::string>& extension_ids) {
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&NotifyNetworkDelaysOnUI, profile, extension_ids));
+}
+
} // namespace
ExtensionWebRequestTimeTracker::RequestTimeLog::RequestTimeLog()
- : completed(false) {
+ : profile(NULL), completed(false) {
}
ExtensionWebRequestTimeTracker::RequestTimeLog::~RequestTimeLog() {
}
-ExtensionWebRequestTimeTracker::ExtensionWebRequestTimeTracker() {
+ExtensionWebRequestTimeTracker::ExtensionWebRequestTimeTracker()
+ : delegate_(new DefaultDelegate) {
}
ExtensionWebRequestTimeTracker::~ExtensionWebRequestTimeTracker() {
}
void ExtensionWebRequestTimeTracker::LogRequestStartTime(
- int64 request_id, const base::Time& start_time, const GURL& url) {
+ int64 request_id,
+ const base::Time& start_time,
+ const GURL& url,
+ void* profile) {
// Trim old completed request logs.
while (request_ids_.size() > kMaxRequestsLogged) {
int64 to_remove = request_ids_.front();
@@ -64,6 +133,7 @@ void ExtensionWebRequestTimeTracker::LogRequestStartTime(
RequestTimeLog& log = request_time_logs_[request_id];
log.request_start_time = start_time;
log.url = url;
+ log.profile = profile;
}
void ExtensionWebRequestTimeTracker::LogRequestEndTime(
@@ -86,6 +156,18 @@ void ExtensionWebRequestTimeTracker::LogRequestEndTime(
Analyze(request_id);
}
+std::set<std::string> ExtensionWebRequestTimeTracker::GetExtensionIds(
+ const RequestTimeLog& log) const {
+ std::set<std::string> result;
+ for (std::map<std::string, base::TimeDelta>::const_iterator i =
+ log.extension_block_durations.begin();
+ i != log.extension_block_durations.end();
+ ++i) {
+ result.insert(i->first);
+ }
+ return result;
+}
+
void ExtensionWebRequestTimeTracker::Analyze(int64 request_id) {
RequestTimeLog& log = request_time_logs_[request_id];
@@ -101,18 +183,31 @@ void ExtensionWebRequestTimeTracker::Analyze(int64 request_id) {
log.block_duration.InMilliseconds() << "/" <<
log.request_duration.InMilliseconds() << " = " << percentage;
- // TODO(mpcomplete): need actual UI for the warning.
// TODO(mpcomplete): blame a specific extension. Maybe go through the list
// of recent requests and find the extension that has caused the most delays.
if (percentage > kThresholdExcessiveDelay) {
excessive_delays_.insert(request_id);
if (excessive_delays_.size() > kNumExcessiveDelaysBeforeWarning) {
LOG(ERROR) << "WR excessive delays:" << excessive_delays_.size();
+ if (delegate_.get()) {
+ delegate_->NotifyExcessiveDelays(log.profile,
+ excessive_delays_.size(),
+ request_ids_.size(),
+ GetExtensionIds(log));
+ }
}
} else if (percentage > kThresholdModerateDelay) {
moderate_delays_.insert(request_id);
- if (moderate_delays_.size() > kNumModerateDelaysBeforeWarning) {
+ if (moderate_delays_.size() + excessive_delays_.size() >
+ kNumModerateDelaysBeforeWarning) {
LOG(ERROR) << "WR moderate delays:" << moderate_delays_.size();
+ if (delegate_.get()) {
+ delegate_->NotifyModerateDelays(
+ log.profile,
+ moderate_delays_.size() + excessive_delays_.size(),
+ request_ids_.size(),
+ GetExtensionIds(log));
+ }
}
}
}
@@ -152,3 +247,8 @@ void ExtensionWebRequestTimeTracker::SetRequestRedirected(int64 request_id) {
// down this request. Just ignore it.
request_time_logs_.erase(request_id);
}
+
+void ExtensionWebRequestTimeTracker::SetDelegate(
+ ExtensionWebRequestTimeTrackerDelegate* delegate) {
+ delegate_.reset(delegate);
+}

Powered by Google App Engine
This is Rietveld 408576698