This adds the plumbing needed to take data about completed outbound
network traffic to the task manager for tracking network usage.
There are a number of naming changes to help distinguish between what
is and isn't a "rate" and what is sent vs read vs transferred. Read being
incoming bytes, sent being outgoing bytes and transfered being either
read or sent bytes.
The "rates" are not calculated based on what is live on the network.
It is instead based on when requests are completed so large uploads
will all be registered in one refresh.
This update changes the struct BytesReadParam to BytesTrasferedParam
and stores both bytes read and bytes sent. It updates how the struct is
processed to handle the additional tracking of sent bytes.
Tasks have been changed to store the cumulative_bytes_read_ and
cumulative_bytes_sent_ which are stored on Refresh() to the
last_refresh_cumulative_bytes_sent_ and
last_refresh_cumulative_bytes_read_ . These are used to calculate
network_sent_rate_ and network_read_rate_ which are summed for the
network_usage_rate_.
Tasks no longer store a network usage of -1 to signify that they have
not had any network traffic, the utility of that flag no longer appears
to be used so it was removed. Because of this ReportsNetworkUsage() has been removed.
Tasks and Task Groups can now report their cumulative network usage.
BUG=720773
Review-Url: https://codereview.chromium.org/2905403002
Cr-Commit-Position: refs/heads/master@{#480988}
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc
index 11dd8dc..fae150e 100644
--- a/chrome/browser/net/chrome_network_delegate.cc
+++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -359,6 +359,12 @@
void ChromeNetworkDelegate::OnNetworkBytesSent(net::URLRequest* request,
int64_t bytes_sent) {
+#if !defined(OS_ANDROID)
+ // Note: Currently, OnNetworkBytesSent is only implemented for HTTP jobs,
+ // not FTP or other types, so those kinds of bytes will not be reported here.
+ task_manager::TaskManagerInterface::OnRawBytesSent(*request, bytes_sent);
+#endif // !defined(OS_ANDROID)
+
ReportDataUsageStats(request, bytes_sent, 0 /* rx_bytes */);
}
diff --git a/chrome/browser/task_manager/providers/browser_process_task_unittest.cc b/chrome/browser/task_manager/providers/browser_process_task_unittest.cc
index 15fbc672b..45ff115f 100644
--- a/chrome/browser/task_manager/providers/browser_process_task_unittest.cc
+++ b/chrome/browser/task_manager/providers/browser_process_task_unittest.cc
@@ -75,14 +75,12 @@
EXPECT_EQ(Task::BROWSER, provided_task_->GetType());
EXPECT_EQ(0, provided_task_->GetChildProcessUniqueID());
const int received_bytes = 1024;
- EXPECT_FALSE(provided_task_->ReportsNetworkUsage());
- EXPECT_EQ(-1, provided_task_->network_usage());
+ EXPECT_EQ(0, provided_task_->network_usage_rate());
provided_task_->OnNetworkBytesRead(received_bytes);
// Do a refresh with a 1-second update time.
provided_task_->Refresh(base::TimeDelta::FromSeconds(1),
REFRESH_TYPE_NETWORK_USAGE);
- EXPECT_TRUE(provided_task_->ReportsNetworkUsage());
- EXPECT_EQ(received_bytes, provided_task_->network_usage());
+ EXPECT_EQ(received_bytes, provided_task_->network_usage_rate());
}
} // namespace task_manager
diff --git a/chrome/browser/task_manager/providers/child_process_task_unittest.cc b/chrome/browser/task_manager/providers/child_process_task_unittest.cc
index e055753..9a9c1fe 100644
--- a/chrome/browser/task_manager/providers/child_process_task_unittest.cc
+++ b/chrome/browser/task_manager/providers/child_process_task_unittest.cc
@@ -131,7 +131,6 @@
EXPECT_FALSE(task->ReportsSqliteMemory());
EXPECT_FALSE(task->ReportsV8Memory());
EXPECT_FALSE(task->ReportsWebCacheStats());
- EXPECT_FALSE(task->ReportsNetworkUsage());
// Make sure that the conversion from PID to Handle inside
// |GetTaskOfUrlRequest()| is working properly.
@@ -143,8 +142,7 @@
found_task->Refresh(base::TimeDelta::FromSeconds(1),
REFRESH_TYPE_NETWORK_USAGE);
- EXPECT_TRUE(task->ReportsNetworkUsage());
- EXPECT_EQ(bytes_read, task->network_usage());
+ EXPECT_EQ(bytes_read, task->network_usage_rate());
// Clearing the observer won't notify us of any tasks removals even though
// tasks will be actually deleted.
diff --git a/chrome/browser/task_manager/providers/task.cc b/chrome/browser/task_manager/providers/task.cc
index a49032f..1306017 100644
--- a/chrome/browser/task_manager/providers/task.cc
+++ b/chrome/browser/task_manager/providers/task.cc
@@ -30,8 +30,12 @@
base::ProcessHandle handle,
base::ProcessId process_id)
: task_id_(g_last_id++),
- network_usage_(-1),
- current_byte_count_(-1),
+ last_refresh_cumulative_bytes_sent_(0),
+ last_refresh_cumulative_bytes_read_(0),
+ cumulative_bytes_sent_(0),
+ cumulative_bytes_read_(0),
+ network_sent_rate_(0),
+ network_read_rate_(0),
title_(title),
rappor_sample_name_(rappor_sample),
icon_(icon ? *icon : gfx::ImageSkia()),
@@ -70,24 +74,32 @@
void Task::Refresh(const base::TimeDelta& update_interval,
int64_t refresh_flags) {
- if ((refresh_flags & REFRESH_TYPE_NETWORK_USAGE) == 0)
+ if ((refresh_flags & REFRESH_TYPE_NETWORK_USAGE) == 0 ||
+ update_interval == base::TimeDelta())
return;
- if (current_byte_count_ == -1)
- return;
+ int64_t current_cycle_read_byte_count =
+ cumulative_bytes_read_ - last_refresh_cumulative_bytes_read_;
+ network_read_rate_ =
+ (current_cycle_read_byte_count * base::TimeDelta::FromSeconds(1)) /
+ update_interval;
- network_usage_ =
- (current_byte_count_ * base::TimeDelta::FromSeconds(1)) / update_interval;
+ int64_t current_cycle_sent_byte_count =
+ cumulative_bytes_sent_ - last_refresh_cumulative_bytes_sent_;
+ network_sent_rate_ =
+ (current_cycle_sent_byte_count * base::TimeDelta::FromSeconds(1)) /
+ update_interval;
- // Reset the current byte count for this task.
- current_byte_count_ = 0;
+ last_refresh_cumulative_bytes_read_ = cumulative_bytes_read_;
+ last_refresh_cumulative_bytes_sent_ = cumulative_bytes_sent_;
}
void Task::OnNetworkBytesRead(int64_t bytes_read) {
- if (current_byte_count_ == -1)
- current_byte_count_ = 0;
+ cumulative_bytes_read_ += bytes_read;
+}
- current_byte_count_ += bytes_read;
+void Task::OnNetworkBytesSent(int64_t bytes_sent) {
+ cumulative_bytes_sent_ += bytes_sent;
}
void Task::GetTerminationStatus(base::TerminationStatus* out_status,
@@ -147,8 +159,4 @@
return -1;
}
-bool Task::ReportsNetworkUsage() const {
- return network_usage_ != -1;
-}
-
} // namespace task_manager
diff --git a/chrome/browser/task_manager/providers/task.h b/chrome/browser/task_manager/providers/task.h
index a3e91cee..e72fae90 100644
--- a/chrome/browser/task_manager/providers/task.h
+++ b/chrome/browser/task_manager/providers/task.h
@@ -85,9 +85,14 @@
// Will receive this notification through the task manager from
// |ChromeNetworkDelegate::OnNetworkBytesReceived()|. The task will add to the
- // |current_byte_count_| in this refresh cycle.
+ // |cummulative_read_bytes_|.
void OnNetworkBytesRead(int64_t bytes_read);
+ // Will receive this notification through the task manager from
+ // |ChromeNetworkDelegate::OnNetworkBytesSent()|. The task will add to the
+ // |cummulative_sent_bytes_| in this refresh cycle.
+ void OnNetworkBytesSent(int64_t bytes_sent);
+
// Returns the task type.
virtual Type GetType() const = 0;
@@ -138,11 +143,22 @@
// Returns the keep-alive counter if the Task is an event page, -1 otherwise.
virtual int GetKeepaliveCount() const;
- // Checking whether the task reports network usage.
- bool ReportsNetworkUsage() const;
-
int64_t task_id() const { return task_id_; }
- int64_t network_usage() const { return network_usage_; }
+
+ // Returns the instantaneous rate, in bytes per second, of network usage
+ // (sent and received), as measured over the last refresh cycle.
+ int64_t network_usage_rate() const {
+ return network_sent_rate_ + network_read_rate_;
+ }
+
+ // Returns the cumulative number of bytes of network use (sent and received)
+ // over the tasks lifetime. It is calculated independently of refreshes and
+ // is based on the current |cumulative_bytes_read_| and
+ // |cumulative_bytes_sent_|.
+ int64_t cumulative_network_usage() const {
+ return cumulative_bytes_sent_ + cumulative_bytes_read_;
+ }
+
const base::string16& title() const { return title_; }
const std::string& rappor_sample_name() const { return rappor_sample_name_; }
const gfx::ImageSkia& icon() const { return icon_; }
@@ -160,14 +176,31 @@
// The unique ID of this task.
const int64_t task_id_;
- // The task's network usage in the current refresh cycle measured in bytes per
- // second. A value of -1 means this task doesn't report network usage data.
- int64_t network_usage_;
+ // The sum of all bytes that have been uploaded from this task calculated at
+ // the last refresh.
+ int64_t last_refresh_cumulative_bytes_sent_;
- // The current network bytes received by this task during the current refresh
- // cycle. A value of -1 means this task has never been notified of any network
- // usage.
- int64_t current_byte_count_;
+ // The sum of all bytes that have been downloaded from this task calculated
+ // at the last refresh.
+ int64_t last_refresh_cumulative_bytes_read_;
+
+ // A continuously updating sum of all bytes that have been uploaded from this
+ // task. It is assigned to |last_refresh_cumulative_bytes_sent_| at the end
+ // of a refresh.
+ int64_t cumulative_bytes_sent_;
+
+ // A continuously updating sum of all bytes that have been downloaded from
+ // this task. It is assigned to |last_refresh_cumulative_bytes_sent_| at the
+ // end of a refresh.
+ int64_t cumulative_bytes_read_;
+
+ // The upload rate (in bytes per second) for this task during the latest
+ // refresh.
+ int64_t network_sent_rate_;
+
+ // The download rate (in bytes per second) for this task during the latest
+ // refresh.
+ int64_t network_read_rate_;
// The title of the task.
base::string16 title_;
diff --git a/chrome/browser/task_manager/sampling/task_group.cc b/chrome/browser/task_manager/sampling/task_group.cc
index ce846005..2250522 100644
--- a/chrome/browser/task_manager/sampling/task_group.cc
+++ b/chrome/browser/task_manager/sampling/task_group.cc
@@ -91,7 +91,8 @@
cpu_usage_(0.0),
gpu_memory_(-1),
memory_state_(base::MemoryState::UNKNOWN),
- per_process_network_usage_(-1),
+ per_process_network_usage_rate_(-1),
+ cumulative_per_process_network_usage_(0),
#if defined(OS_WIN)
gdi_current_handles_(-1),
gdi_peak_handles_(-1),
@@ -155,7 +156,6 @@
int64_t refresh_flags) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(!empty());
-
expected_on_bg_done_flags_ = refresh_flags & kBackgroundRefreshTypesMask;
// If a refresh type was recently disabled, we need to account for that too.
current_on_bg_done_flags_ &= expected_on_bg_done_flags_;
@@ -165,12 +165,15 @@
const bool network_usage_refresh_enabled =
TaskManagerObserver::IsResourceRefreshEnabled(REFRESH_TYPE_NETWORK_USAGE,
refresh_flags);
- per_process_network_usage_ = network_usage_refresh_enabled ? 0 : -1;
+
+ per_process_network_usage_rate_ = network_usage_refresh_enabled ? 0 : -1;
+ cumulative_per_process_network_usage_ = 0;
for (Task* task : tasks_) {
task->Refresh(update_interval, refresh_flags);
-
- if (network_usage_refresh_enabled && task->ReportsNetworkUsage())
- per_process_network_usage_ += task->network_usage();
+ if (network_usage_refresh_enabled) {
+ per_process_network_usage_rate_ += task->network_usage_rate();
+ cumulative_per_process_network_usage_ += task->cumulative_network_usage();
+ }
}
// 2- Refresh GPU memory (if enabled).
diff --git a/chrome/browser/task_manager/sampling/task_group.h b/chrome/browser/task_manager/sampling/task_group.h
index 7768367..6e84a61 100644
--- a/chrome/browser/task_manager/sampling/task_group.h
+++ b/chrome/browser/task_manager/sampling/task_group.h
@@ -80,8 +80,11 @@
int64_t gpu_memory() const { return gpu_memory_; }
bool gpu_memory_has_duplicates() const { return gpu_memory_has_duplicates_; }
base::MemoryState memory_state() const { return memory_state_; }
- int64_t per_process_network_usage() const {
- return per_process_network_usage_;
+ int64_t per_process_network_usage_rate() const {
+ return per_process_network_usage_rate_;
+ }
+ int64_t cumulative_per_process_network_usage() const {
+ return cumulative_per_process_network_usage_;
}
bool is_backgrounded() const { return is_backgrounded_; }
@@ -162,7 +165,12 @@
base::MemoryState memory_state_;
// The network usage in bytes per second as the sum of all network usages of
// the individual tasks sharing the same process.
- int64_t per_process_network_usage_;
+ int64_t per_process_network_usage_rate_;
+
+ // A continuously updating sum of all bytes that have been downloaded and
+ // uploaded by all tasks in this process.
+ int64_t cumulative_per_process_network_usage_;
+
#if defined(OS_WIN)
// Windows GDI and USER Handles.
int64_t gdi_current_handles_;
diff --git a/chrome/browser/task_manager/sampling/task_group_unittest.cc b/chrome/browser/task_manager/sampling/task_group_unittest.cc
index 19e640b1..8852e46a 100644
--- a/chrome/browser/task_manager/sampling/task_group_unittest.cc
+++ b/chrome/browser/task_manager/sampling/task_group_unittest.cc
@@ -166,4 +166,355 @@
EXPECT_TRUE(task_group_.AreBackgroundCalculationsDone());
}
+// Test the task has correct network usage rate when zero bytes read and sent.
+TEST_F(TaskGroupTest, NetworkBytesSentReadZero) {
+ const int zero_bytes = 0;
+ FakeTask fake_task(base::Process::Current().Pid(), Task::RENDERER);
+ fake_task.OnNetworkBytesRead(zero_bytes);
+ fake_task.Refresh(base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(zero_bytes, fake_task.network_usage_rate());
+ fake_task.OnNetworkBytesSent(zero_bytes);
+ fake_task.Refresh(base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(zero_bytes, fake_task.network_usage_rate());
+}
+
+// Test the task has correct network usage rate when only having read bytes.
+TEST_F(TaskGroupTest, NetworkBytesRead) {
+ const int read_bytes = 1024;
+ FakeTask fake_task(base::Process::Current().Pid(), Task::RENDERER);
+ fake_task.OnNetworkBytesRead(read_bytes);
+ EXPECT_EQ(0, fake_task.network_usage_rate());
+ EXPECT_EQ(read_bytes, fake_task.cumulative_network_usage());
+ fake_task.Refresh(base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(read_bytes, fake_task.network_usage_rate());
+ EXPECT_EQ(read_bytes, fake_task.cumulative_network_usage());
+}
+
+// Test the task has correct network usage rate when only having sent bytes.
+TEST_F(TaskGroupTest, NetworkBytesSent) {
+ const int sent_bytes = 1023;
+ FakeTask fake_task(base::Process::Current().Pid(), Task::RENDERER);
+ fake_task.OnNetworkBytesSent(sent_bytes);
+ EXPECT_EQ(0, fake_task.network_usage_rate());
+ EXPECT_EQ(sent_bytes, fake_task.cumulative_network_usage());
+ fake_task.Refresh(base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(sent_bytes, fake_task.network_usage_rate());
+ EXPECT_EQ(sent_bytes, fake_task.cumulative_network_usage());
+}
+
+// Test the task has correct network usage rate when only having read bytes and
+// having a non 1s refresh time.
+TEST_F(TaskGroupTest, NetworkBytesRead2SecRefresh) {
+ const int refresh_secs = 2;
+ const int read_bytes = 1024 * refresh_secs; // for integer division
+ FakeTask fake_task(base::Process::Current().Pid(), Task::RENDERER);
+ fake_task.OnNetworkBytesRead(read_bytes);
+ EXPECT_EQ(0, fake_task.network_usage_rate());
+ EXPECT_EQ(read_bytes, fake_task.cumulative_network_usage());
+ fake_task.Refresh(base::TimeDelta::FromSeconds(refresh_secs),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(read_bytes / refresh_secs, fake_task.network_usage_rate());
+ EXPECT_EQ(read_bytes, fake_task.cumulative_network_usage());
+}
+
+// Test the task has correct network usage rate when only having sent bytes and
+// having a non 1s refresh time.
+TEST_F(TaskGroupTest, NetworkBytesSent2SecRefresh) {
+ const int refresh_secs = 2;
+ const int sent_bytes = 1023 * refresh_secs; // for integer division
+ FakeTask fake_task(base::Process::Current().Pid(), Task::RENDERER);
+ fake_task.OnNetworkBytesSent(sent_bytes);
+ EXPECT_EQ(0, fake_task.network_usage_rate());
+ EXPECT_EQ(sent_bytes, fake_task.cumulative_network_usage());
+ fake_task.Refresh(base::TimeDelta::FromSeconds(refresh_secs),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(sent_bytes / refresh_secs, fake_task.network_usage_rate());
+ EXPECT_EQ(sent_bytes, fake_task.cumulative_network_usage());
+}
+
+// Tests the task has correct usage on receiving and then sending bytes.
+TEST_F(TaskGroupTest, NetworkBytesReadThenSent) {
+ const int read_bytes = 124;
+ const int sent_bytes = 1027;
+ FakeTask fake_task(base::Process::Current().Pid(), Task::RENDERER);
+ fake_task.OnNetworkBytesRead(read_bytes);
+ EXPECT_EQ(read_bytes, fake_task.cumulative_network_usage());
+ fake_task.OnNetworkBytesSent(sent_bytes);
+ fake_task.Refresh(base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(read_bytes + sent_bytes, fake_task.network_usage_rate());
+ EXPECT_EQ(read_bytes + sent_bytes, fake_task.cumulative_network_usage());
+}
+
+// Tests the task has correct usage rate on sending and then receiving bytes.
+TEST_F(TaskGroupTest, NetworkBytesSentThenRead) {
+ const int read_bytes = 1025;
+ const int sent_bytes = 10;
+ FakeTask fake_task(base::Process::Current().Pid(), Task::RENDERER);
+ fake_task.OnNetworkBytesSent(sent_bytes);
+ fake_task.OnNetworkBytesRead(read_bytes);
+ fake_task.Refresh(base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(read_bytes + sent_bytes, fake_task.network_usage_rate());
+}
+
+// Tests that the network usage rate goes to 0 after reading bytes then a
+// refresh with no traffic and that cumulative is still correct.
+TEST_F(TaskGroupTest, NetworkBytesReadRefreshNone) {
+ const int read_bytes = 1024;
+ FakeTask fake_task(base::Process::Current().Pid(), Task::RENDERER);
+ fake_task.OnNetworkBytesRead(read_bytes);
+ fake_task.Refresh(base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ // Refresh to zero out the usage rate.
+ fake_task.Refresh(base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(0, fake_task.network_usage_rate());
+ EXPECT_EQ(read_bytes, fake_task.cumulative_network_usage());
+}
+
+// Tests that the network usage rate goes to 0 after sending bytes then a
+// refresh with no traffic and that cumulative is still correct.
+TEST_F(TaskGroupTest, NetworkBytesSentRefreshNone) {
+ const int sent_bytes = 1024;
+ FakeTask fake_task(base::Process::Current().Pid(), Task::RENDERER);
+ fake_task.OnNetworkBytesSent(sent_bytes);
+ fake_task.Refresh(base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ // Refresh to zero out the usage rate.
+ fake_task.Refresh(base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(0, fake_task.network_usage_rate());
+ EXPECT_EQ(sent_bytes, fake_task.cumulative_network_usage());
+}
+
+// Tests that the network usage rate goes to 0 after a refresh with no traffic
+// and that cumulative is still correct.
+TEST_F(TaskGroupTest, NetworkBytesTransferredRefreshNone) {
+ const int read_bytes = 1024;
+ const int sent_bytes = 1;
+ const int number_of_cycles = 2;
+ FakeTask fake_task(base::Process::Current().Pid(), Task::RENDERER);
+ for (int i = 0; i < number_of_cycles; i++) {
+ fake_task.OnNetworkBytesRead(read_bytes);
+ fake_task.Refresh(base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ fake_task.OnNetworkBytesSent(sent_bytes);
+ fake_task.Refresh(base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ }
+ // Refresh to zero out the usage rate.
+ fake_task.Refresh(base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(0, fake_task.network_usage_rate());
+ EXPECT_EQ((read_bytes + sent_bytes) * number_of_cycles,
+ fake_task.cumulative_network_usage());
+}
+
+// Tests that 2 tasks in 1 task group that both read bytes have correct usage
+// rates and correct cumulative network usage.
+TEST_F(TaskGroupTest, NetworkBytesReadAsGroup) {
+ const int read_bytes1 = 1024;
+ const int read_bytes2 = 789;
+ const int number_of_cycles = 2;
+ FakeTask fake_task1(base::Process::Current().Pid(), Task::RENDERER);
+ FakeTask fake_task2(base::Process::Current().Pid(), Task::RENDERER);
+
+ task_group_.AddTask(&fake_task1);
+ task_group_.AddTask(&fake_task2);
+
+ for (int i = 0; i < number_of_cycles; i++) {
+ fake_task1.OnNetworkBytesRead(read_bytes1);
+ fake_task2.OnNetworkBytesRead(read_bytes2);
+ task_group_.Refresh(gpu::VideoMemoryUsageStats(),
+ base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(read_bytes1 + read_bytes2,
+ task_group_.per_process_network_usage_rate());
+ }
+
+ EXPECT_EQ((read_bytes1 + read_bytes2) * number_of_cycles,
+ task_group_.cumulative_per_process_network_usage());
+}
+
+// Tests that the network usage rate does not get affected until a refresh is
+// called and that the cumulative is as up to date as possible
+TEST_F(TaskGroupTest, NetworkBytesTransferredRefreshOutOfOrder) {
+ const int read_bytes = 1024;
+ const int sent_bytes = 1;
+ const int number_of_cycles = 4;
+ int number_of_bytes_transferred = 0;
+ FakeTask fake_task(base::Process::Current().Pid(), Task::RENDERER);
+ for (int i = 0; i < number_of_cycles; i++) {
+ fake_task.OnNetworkBytesRead(read_bytes * i);
+ number_of_bytes_transferred += read_bytes * i;
+ EXPECT_EQ(number_of_bytes_transferred,
+ fake_task.cumulative_network_usage());
+ fake_task.OnNetworkBytesSent(sent_bytes * i);
+ number_of_bytes_transferred += sent_bytes * i;
+ EXPECT_EQ(number_of_bytes_transferred,
+ fake_task.cumulative_network_usage());
+ if (i > 0) {
+ EXPECT_EQ((read_bytes + sent_bytes) * (i - 1),
+ fake_task.network_usage_rate());
+ }
+ fake_task.Refresh(base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ((read_bytes + sent_bytes) * i, fake_task.network_usage_rate());
+ }
+ // Refresh to zero out the usage rate.
+ fake_task.Refresh(base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(0, fake_task.network_usage_rate());
+ EXPECT_EQ(number_of_bytes_transferred, fake_task.cumulative_network_usage());
+}
+
+// Tests that 2 tasks in 1 task group that both sent bytes have correct usage
+// rates and correct cumulative network usage.
+TEST_F(TaskGroupTest, NetworkBytesSentAsGroup) {
+ const int sent_bytes1 = 1123;
+ const int sent_bytes2 = 778;
+ FakeTask fake_task1(base::Process::Current().Pid(), Task::RENDERER);
+ FakeTask fake_task2(base::Process::Current().Pid(), Task::RENDERER);
+
+ task_group_.AddTask(&fake_task1);
+ task_group_.AddTask(&fake_task2);
+
+ fake_task1.OnNetworkBytesSent(sent_bytes1);
+ fake_task2.OnNetworkBytesSent(sent_bytes2);
+ task_group_.Refresh(gpu::VideoMemoryUsageStats(),
+ base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(sent_bytes1 + sent_bytes2,
+ task_group_.per_process_network_usage_rate());
+
+ fake_task1.OnNetworkBytesSent(sent_bytes1);
+ fake_task2.OnNetworkBytesSent(sent_bytes2);
+ task_group_.Refresh(gpu::VideoMemoryUsageStats(),
+ base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+
+ EXPECT_EQ((sent_bytes1 + sent_bytes2) * 2,
+ task_group_.cumulative_per_process_network_usage());
+}
+
+// Tests that 2 tasks in 1 task group that have one sending and one reading
+// have correct usage rates for the group and correct cumulative network usage.
+TEST_F(TaskGroupTest, NetworkBytesTransferredAsGroup) {
+ const int sent_bytes = 1023;
+ const int read_bytes = 678;
+ const int number_of_cycles = 2;
+ FakeTask fake_task1(base::Process::Current().Pid(), Task::RENDERER);
+ FakeTask fake_task2(base::Process::Current().Pid(), Task::RENDERER);
+
+ task_group_.AddTask(&fake_task1);
+ task_group_.AddTask(&fake_task2);
+ for (int i = 0; i < number_of_cycles; i++) {
+ fake_task1.OnNetworkBytesSent(sent_bytes);
+ fake_task2.OnNetworkBytesRead(read_bytes);
+ task_group_.Refresh(gpu::VideoMemoryUsageStats(),
+ base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(sent_bytes + read_bytes,
+ task_group_.per_process_network_usage_rate());
+ }
+
+ EXPECT_EQ((read_bytes + sent_bytes) * number_of_cycles,
+ task_group_.cumulative_per_process_network_usage());
+}
+
+// Tests that after two tasks in a task group read bytes that a refresh will
+// zero out network usage rate while maintaining the correct cumulative network
+// usage
+TEST_F(TaskGroupTest, NetworkBytesReadAsGroupThenNone) {
+ const int read_bytes1 = 1013;
+ const int read_bytes2 = 679;
+ const int number_of_cycles = 2;
+ FakeTask fake_task1(base::Process::Current().Pid(), Task::RENDERER);
+ FakeTask fake_task2(base::Process::Current().Pid(), Task::RENDERER);
+
+ task_group_.AddTask(&fake_task1);
+ task_group_.AddTask(&fake_task2);
+
+ for (int i = 0; i < number_of_cycles; i++) {
+ fake_task1.OnNetworkBytesRead(read_bytes1);
+ fake_task2.OnNetworkBytesRead(read_bytes2);
+ task_group_.Refresh(gpu::VideoMemoryUsageStats(),
+ base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(read_bytes1 + read_bytes2,
+ task_group_.per_process_network_usage_rate());
+ }
+ task_group_.Refresh(gpu::VideoMemoryUsageStats(),
+ base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(0, task_group_.per_process_network_usage_rate());
+ EXPECT_EQ((read_bytes1 + read_bytes2) * number_of_cycles,
+ task_group_.cumulative_per_process_network_usage());
+}
+
+// Tests that after two tasks in a task group send bytes that a refresh will
+// zero out network usage rate while maintaining the correct cumulative network
+// usage
+TEST_F(TaskGroupTest, NetworkBytesSentAsGroupThenNone) {
+ const int sent_bytes1 = 1023;
+ const int sent_bytes2 = 678;
+ const int number_of_cycles = 2;
+ FakeTask fake_task1(base::Process::Current().Pid(), Task::RENDERER);
+ FakeTask fake_task2(base::Process::Current().Pid(), Task::RENDERER);
+
+ task_group_.AddTask(&fake_task1);
+ task_group_.AddTask(&fake_task2);
+
+ for (int i = 0; i < number_of_cycles; i++) {
+ fake_task1.OnNetworkBytesSent(sent_bytes1);
+ fake_task2.OnNetworkBytesSent(sent_bytes2);
+ task_group_.Refresh(gpu::VideoMemoryUsageStats(),
+ base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(sent_bytes1 + sent_bytes2,
+ task_group_.per_process_network_usage_rate());
+ }
+ task_group_.Refresh(gpu::VideoMemoryUsageStats(),
+ base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(0, task_group_.per_process_network_usage_rate());
+ EXPECT_EQ((sent_bytes1 + sent_bytes2) * number_of_cycles,
+ task_group_.cumulative_per_process_network_usage());
+}
+
+// Tests that after two tasks in a task group transferred bytes that a refresh
+// will zero out network usage rate while maintaining the correct cumulative
+// network usage
+TEST_F(TaskGroupTest, NetworkBytesTransferredAsGroupThenNone) {
+ const int read_bytes = 321;
+ const int sent_bytes = 987;
+ const int number_of_cycles = 3;
+ FakeTask fake_task1(base::Process::Current().Pid(), Task::RENDERER);
+ FakeTask fake_task2(base::Process::Current().Pid(), Task::RENDERER);
+
+ task_group_.AddTask(&fake_task1);
+ task_group_.AddTask(&fake_task2);
+
+ for (int i = 0; i < number_of_cycles; i++) {
+ fake_task1.OnNetworkBytesRead(read_bytes);
+ fake_task2.OnNetworkBytesSent(sent_bytes);
+ task_group_.Refresh(gpu::VideoMemoryUsageStats(),
+ base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(read_bytes + sent_bytes,
+ task_group_.per_process_network_usage_rate());
+ }
+ task_group_.Refresh(gpu::VideoMemoryUsageStats(),
+ base::TimeDelta::FromSeconds(1),
+ REFRESH_TYPE_NETWORK_USAGE);
+ EXPECT_EQ(0, task_group_.per_process_network_usage_rate());
+ EXPECT_EQ((read_bytes + sent_bytes) * number_of_cycles,
+ task_group_.cumulative_per_process_network_usage());
+}
+
} // namespace task_manager
diff --git a/chrome/browser/task_manager/sampling/task_manager_impl.cc b/chrome/browser/task_manager/sampling/task_manager_impl.cc
index ca2dbb8b..9cae990 100644
--- a/chrome/browser/task_manager/sampling/task_manager_impl.cc
+++ b/chrome/browser/task_manager/sampling/task_manager_impl.cc
@@ -228,11 +228,20 @@
}
int64_t TaskManagerImpl::GetNetworkUsage(TaskId task_id) const {
- return GetTaskByTaskId(task_id)->network_usage();
+ return GetTaskByTaskId(task_id)->network_usage_rate();
+}
+
+int64_t TaskManagerImpl::GetCumulativeNetworkUsage(TaskId task_id) const {
+ return GetTaskByTaskId(task_id)->cumulative_network_usage();
}
int64_t TaskManagerImpl::GetProcessTotalNetworkUsage(TaskId task_id) const {
- return GetTaskGroupByTaskId(task_id)->per_process_network_usage();
+ return GetTaskGroupByTaskId(task_id)->per_process_network_usage_rate();
+}
+
+int64_t TaskManagerImpl::GetCumulativeProcessTotalNetworkUsage(
+ TaskId task_id) const {
+ return GetTaskGroupByTaskId(task_id)->cumulative_per_process_network_usage();
}
int64_t TaskManagerImpl::GetSqliteMemoryUsed(TaskId task_id) const {
@@ -446,13 +455,13 @@
}
// static
-void TaskManagerImpl::OnMultipleBytesReadUI(
- std::vector<BytesReadParam>* params) {
+void TaskManagerImpl::OnMultipleBytesTransferredUI(
+ std::vector<BytesTransferredParam>* params) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(params);
- for (BytesReadParam& param : *params) {
- if (!GetInstance()->UpdateTasksWithBytesRead(param)) {
+ for (BytesTransferredParam& param : *params) {
+ if (!GetInstance()->UpdateTasksWithBytesTransferred(param)) {
// We can't match a task to the notification. That might mean the
// tab that started a download was closed, or the request may have had
// no originating task associated with it in the first place.
@@ -461,8 +470,7 @@
param.origin_pid = 0;
param.child_id = param.route_id = -1;
-
- GetInstance()->UpdateTasksWithBytesRead(param);
+ GetInstance()->UpdateTasksWithBytesTransferred(param);
}
}
}
@@ -530,13 +538,15 @@
return nullptr;
}
-bool TaskManagerImpl::UpdateTasksWithBytesRead(const BytesReadParam& param) {
+bool TaskManagerImpl::UpdateTasksWithBytesTransferred(
+ const BytesTransferredParam& param) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
Task* task =
GetTaskByPidOrRoute(param.origin_pid, param.child_id, param.route_id);
if (task) {
- task->OnNetworkBytesRead(param.byte_count);
+ task->OnNetworkBytesRead(param.byte_read_count);
+ task->OnNetworkBytesSent(param.byte_sent_count);
return true;
}
diff --git a/chrome/browser/task_manager/sampling/task_manager_impl.h b/chrome/browser/task_manager/sampling/task_manager_impl.h
index b4834943..5e1ef98 100644
--- a/chrome/browser/task_manager/sampling/task_manager_impl.h
+++ b/chrome/browser/task_manager/sampling/task_manager_impl.h
@@ -74,7 +74,9 @@
base::TerminationStatus* out_status,
int* out_error_code) const override;
int64_t GetNetworkUsage(TaskId task_id) const override;
+ int64_t GetCumulativeNetworkUsage(TaskId task_id) const override;
int64_t GetProcessTotalNetworkUsage(TaskId task_id) const override;
+ int64_t GetCumulativeProcessTotalNetworkUsage(TaskId task_id) const override;
int64_t GetSqliteMemoryUsed(TaskId task_id) const override;
bool GetV8Memory(TaskId task_id,
int64_t* allocated,
@@ -94,9 +96,11 @@
void TaskRemoved(Task* task) override;
void TaskUnresponsive(Task* task) override;
- // The notification method on the UI thread when multiple bytes are read
- // from URLRequests. This will be called by the |io_thread_helper_|
- static void OnMultipleBytesReadUI(std::vector<BytesReadParam>* params);
+ // The notification method on the UI thread when multiple bytes are
+ // transferred from URLRequests. This will be called by the
+ // |io_thread_helper_|
+ static void OnMultipleBytesTransferredUI(
+ std::vector<BytesTransferredParam>* params);
private:
friend struct base::LazyInstanceTraitsBase<TaskManagerImpl>;
@@ -119,7 +123,7 @@
// false otherwise, at which point the caller must explicitly match these
// bytes to the browser process by calling this method again with
// |param.origin_pid = 0| and |param.child_id = param.route_id = -1|.
- bool UpdateTasksWithBytesRead(const BytesReadParam& param);
+ bool UpdateTasksWithBytesTransferred(const BytesTransferredParam& param);
TaskGroup* GetTaskGroupByTaskId(TaskId task_id) const;
Task* GetTaskByTaskId(TaskId task_id) const;
diff --git a/chrome/browser/task_manager/sampling/task_manager_io_thread_helper.cc b/chrome/browser/task_manager/sampling/task_manager_io_thread_helper.cc
index ae01667..63c53974 100644
--- a/chrome/browser/task_manager/sampling/task_manager_io_thread_helper.cc
+++ b/chrome/browser/task_manager/sampling/task_manager_io_thread_helper.cc
@@ -59,8 +59,23 @@
int64_t bytes_read) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (g_io_thread_helper)
- g_io_thread_helper->OnNetworkBytesRead(request, bytes_read);
+ if (g_io_thread_helper) {
+ int64_t bytes_sent = 0;
+ g_io_thread_helper->OnNetworkBytesTransferred(request, bytes_read,
+ bytes_sent);
+ }
+}
+
+// static
+void TaskManagerIoThreadHelper::OnRawBytesSent(const net::URLRequest& request,
+ int64_t bytes_sent) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ if (g_io_thread_helper) {
+ int64_t bytes_read = 0;
+ g_io_thread_helper->OnNetworkBytesTransferred(request, bytes_read,
+ bytes_sent);
+ }
}
TaskManagerIoThreadHelper::TaskManagerIoThreadHelper() : weak_factory_(this) {
@@ -71,24 +86,25 @@
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
}
-void TaskManagerIoThreadHelper::OnMultipleBytesReadIO() {
+void TaskManagerIoThreadHelper::OnMultipleBytesTransferredIO() {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(!bytes_read_buffer_.empty());
+ DCHECK(!bytes_transferred_buffer_.empty());
- std::vector<BytesReadParam>* bytes_read_buffer =
- new std::vector<BytesReadParam>();
- bytes_read_buffer_.swap(*bytes_read_buffer);
+ std::vector<BytesTransferredParam>* bytes_read_buffer =
+ new std::vector<BytesTransferredParam>();
+ bytes_transferred_buffer_.swap(*bytes_read_buffer);
content::BrowserThread::PostTask(
- content::BrowserThread::UI,
- FROM_HERE,
- base::Bind(&TaskManagerImpl::OnMultipleBytesReadUI,
+ content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&TaskManagerImpl::OnMultipleBytesTransferredUI,
base::Owned(bytes_read_buffer)));
}
-void TaskManagerIoThreadHelper::OnNetworkBytesRead(
- const net::URLRequest& request, int64_t bytes_read) {
+void TaskManagerIoThreadHelper::OnNetworkBytesTransferred(
+ const net::URLRequest& request,
+ int64_t bytes_read,
+ int64_t bytes_sent) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
// Only net::URLRequestJob instances created by the ResourceDispatcherHost
@@ -107,7 +123,7 @@
// plugins - for renderer or browser initiated requests it will be zero.
int origin_pid = info ? info->GetOriginPID() : 0;
- if (bytes_read_buffer_.empty()) {
+ if (bytes_transferred_buffer_.empty()) {
// Schedule a task to process the received bytes requests a second from now.
// We're trying to calculate the tasks' network usage speed as bytes per
// second so we collect as many requests during one seconds before the below
@@ -115,13 +131,13 @@
// after one second from now.
content::BrowserThread::PostDelayedTask(
content::BrowserThread::IO, FROM_HERE,
- base::Bind(&TaskManagerIoThreadHelper::OnMultipleBytesReadIO,
+ base::Bind(&TaskManagerIoThreadHelper::OnMultipleBytesTransferredIO,
weak_factory_.GetWeakPtr()),
base::TimeDelta::FromSeconds(1));
}
- bytes_read_buffer_.push_back(
- BytesReadParam(origin_pid, child_id, route_id, bytes_read));
+ bytes_transferred_buffer_.push_back(BytesTransferredParam(
+ origin_pid, child_id, route_id, bytes_read, bytes_sent));
}
} // namespace task_manager
diff --git a/chrome/browser/task_manager/sampling/task_manager_io_thread_helper.h b/chrome/browser/task_manager/sampling/task_manager_io_thread_helper.h
index ff5315b..321025fa 100644
--- a/chrome/browser/task_manager/sampling/task_manager_io_thread_helper.h
+++ b/chrome/browser/task_manager/sampling/task_manager_io_thread_helper.h
@@ -19,13 +19,13 @@
namespace task_manager {
// Defines a wrapper of values that will be sent from IO to UI thread upon
-// reception of bytes read notifications.
-struct BytesReadParam {
+// reception and transmission of bytes notifications.
+struct BytesTransferredParam {
// The PID of the originating process of the URLRequest, if the request is
// sent on behalf of another process. Otherwise it's 0.
int origin_pid;
- // The unique ID of the host of the child process requestor.
+ // The unique ID of the host of the child process requester.
int child_id;
// The ID of the IPC route for the URLRequest (this identifies the
@@ -34,17 +34,21 @@
int route_id;
// The number of bytes read.
- int64_t byte_count;
+ int64_t byte_read_count;
- BytesReadParam(int origin_pid,
- int child_id,
- int route_id,
- int64_t byte_count)
+ // The number of bytes sent.
+ int64_t byte_sent_count;
+
+ BytesTransferredParam(int origin_pid,
+ int child_id,
+ int route_id,
+ int64_t byte_read_count,
+ int64_t byte_sent_count)
: origin_pid(origin_pid),
child_id(child_id),
route_id(route_id),
- byte_count(byte_count) {
- }
+ byte_read_count(byte_read_count),
+ byte_sent_count(byte_sent_count) {}
};
// Defines a utility class used to schedule the creation and removal of the
@@ -59,7 +63,7 @@
};
// Defines a class used by the task manager to receive notifications of the
-// network bytes read by the various tasks.
+// network bytes transferred by the various tasks.
// This object lives entirely only on the IO thread.
class TaskManagerIoThreadHelper {
public:
@@ -68,25 +72,33 @@
static void CreateInstance();
static void DeleteInstance();
- // This is used to forward the call to update the network bytes from the
- // TaskManagerInterface if the new task manager is enabled.
+ // This is used to forward the call to update the network bytes with read
+ // bytes from the TaskManagerInterface if the new task manager is enabled.
static void OnRawBytesRead(const net::URLRequest& request,
int64_t bytes_read);
+ // This is used to forward the call to update the network bytes with sent
+ // bytes from the TaskManagerInterface if the new task manager is enabled.
+ static void OnRawBytesSent(const net::URLRequest& request,
+ int64_t bytes_sent);
+
private:
TaskManagerIoThreadHelper();
~TaskManagerIoThreadHelper();
// We gather multiple notifications on the IO thread in one second before a
- // call is made to the following function to start the processing.
- void OnMultipleBytesReadIO();
+ // call is made to the following function to start the processing for
+ // transferred bytes.
+ void OnMultipleBytesTransferredIO();
// This will update the task manager with the network bytes read.
- void OnNetworkBytesRead(const net::URLRequest& request, int64_t bytes_read);
+ void OnNetworkBytesTransferred(const net::URLRequest& request,
+ int64_t bytes_read,
+ int64_t bytes_sent);
// This buffer will be filled on IO thread with information about the number
- // of bytes read from URLRequests.
- std::vector<BytesReadParam> bytes_read_buffer_;
+ // of bytes transferred from URLRequests.
+ std::vector<BytesTransferredParam> bytes_transferred_buffer_;
base::WeakPtrFactory<TaskManagerIoThreadHelper> weak_factory_;
diff --git a/chrome/browser/task_manager/task_manager_browsertest.cc b/chrome/browser/task_manager/task_manager_browsertest.cc
index 51e133c..9641163 100644
--- a/chrome/browser/task_manager/task_manager_browsertest.cc
+++ b/chrome/browser/task_manager/task_manager_browsertest.cc
@@ -672,6 +672,80 @@
ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchTab("title1.html")));
}
+IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, SentDataObserved) {
+ ShowTaskManager();
+ GURL test_gurl = embedded_test_server()->GetURL("/title1.html");
+
+ ui_test_utils::NavigateToURL(browser(), test_gurl);
+ std::string test_js = R"(
+ document.title = 'network use';
+ var mem = new Uint8Array(16 << 20);
+ for (var i = 0; i < mem.length; i += 16) {
+ mem[i] = i;
+ }
+ var formData = new FormData();
+ formData.append('StringKey1', new Blob([mem]));
+ var request =
+ new Request(location.href, {method: 'POST', body: formData});
+ fetch(request).then(response => response.text());
+ )";
+
+ browser()
+ ->tab_strip_model()
+ ->GetActiveWebContents()
+ ->GetMainFrame()
+ ->ExecuteJavaScriptForTests(base::UTF8ToUTF16(test_js));
+ // TODO(cburn): The assertion below currently assumes that the rate
+ // contribution of the entire 16MB upload arrives in a single refresh cycle.
+ // That's true now because it's only reported when the transaction completes,
+ // but if that changes in the future, this assertion may need to change.
+ ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerStatToExceed(
+ MatchTab("network use"), ColumnSpecifier::NETWORK_USE, 16000000));
+}
+
+IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, TotalSentDataObserved) {
+ ShowTaskManager();
+ GURL test_gurl = embedded_test_server()->GetURL("/title1.html");
+
+ ui_test_utils::NavigateToURL(browser(), test_gurl);
+ std::string test_js = R"(
+ document.title = 'network use';
+ var mem = new Uint8Array(16 << 20);
+ for (var i = 0; i < mem.length; i += 16) {
+ mem[i] = i;
+ }
+ var formData = new FormData();
+ formData.append('StringKey1', new Blob([mem]));
+ var request =
+ new Request(location.href, {method: 'POST', body: formData});
+ fetch(request).then(response => response.text());
+ )";
+
+ browser()
+ ->tab_strip_model()
+ ->GetActiveWebContents()
+ ->GetMainFrame()
+ ->ExecuteJavaScriptForTests(base::UTF8ToUTF16(test_js));
+
+ // This test uses |setTimeout| to exceed the Nyquist ratio to ensure that at
+ // least 1 refresh has happened of no traffic.
+ test_js = R"(
+ var request =
+ new Request(location.href, {method: 'POST', body: formData});
+ setTimeout(
+ () => {fetch(request).then(response => response.text())}, 2000);
+ )";
+
+ browser()
+ ->tab_strip_model()
+ ->GetActiveWebContents()
+ ->GetMainFrame()
+ ->ExecuteJavaScriptForTests(base::UTF8ToUTF16(test_js));
+ ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerStatToExceed(
+ MatchTab("network use"), ColumnSpecifier::TOTAL_NETWORK_USE,
+ 16000000 * 2));
+}
+
// Checks that task manager counts idle wakeups.
// Flakily fails on Mac: http://crbug.com/639939
#if defined(OS_MACOSX)
diff --git a/chrome/browser/task_manager/task_manager_browsertest_util.cc b/chrome/browser/task_manager/task_manager_browsertest_util.cc
index 5da52d1..fd5f2761 100644
--- a/chrome/browser/task_manager/task_manager_browsertest_util.cc
+++ b/chrome/browser/task_manager/task_manager_browsertest_util.cc
@@ -116,6 +116,10 @@
return "Idle wake ups";
case ColumnSpecifier::MEMORY_STATE:
return "Memory State";
+ case ColumnSpecifier::NETWORK_USE:
+ return "Network";
+ case ColumnSpecifier::TOTAL_NETWORK_USE:
+ return "Total Network";
}
return "N/A";
}
diff --git a/chrome/browser/task_manager/task_manager_browsertest_util.h b/chrome/browser/task_manager/task_manager_browsertest_util.h
index a22f739e..0802e6ef 100644
--- a/chrome/browser/task_manager/task_manager_browsertest_util.h
+++ b/chrome/browser/task_manager/task_manager_browsertest_util.h
@@ -26,6 +26,8 @@
SQLITE_MEMORY_USED,
IDLE_WAKEUPS,
MEMORY_STATE,
+ NETWORK_USE,
+ TOTAL_NETWORK_USE,
COLUMN_NONE, // Default value.
};
diff --git a/chrome/browser/task_manager/task_manager_interface.cc b/chrome/browser/task_manager/task_manager_interface.cc
index c4a32857..2b833ec9 100644
--- a/chrome/browser/task_manager/task_manager_interface.cc
+++ b/chrome/browser/task_manager/task_manager_interface.cc
@@ -47,6 +47,13 @@
TaskManagerIoThreadHelper::OnRawBytesRead(request, bytes_read);
}
+// static
+void TaskManagerInterface::OnRawBytesSent(const net::URLRequest& request,
+ int64_t bytes_sent) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ TaskManagerIoThreadHelper::OnRawBytesSent(request, bytes_sent);
+}
+
void TaskManagerInterface::AddObserver(TaskManagerObserver* observer) {
observers_.AddObserver(observer);
observer->observed_task_manager_ = this;
diff --git a/chrome/browser/task_manager/task_manager_interface.h b/chrome/browser/task_manager/task_manager_interface.h
index c4e31c24..fcd9c32a 100644
--- a/chrome/browser/task_manager/task_manager_interface.h
+++ b/chrome/browser/task_manager/task_manager_interface.h
@@ -51,10 +51,15 @@
static TaskManagerInterface* GetTaskManager();
// This notification will be received on the IO thread from
- // ChromeNetworkDelegate to update the task manager with network usage.
+ // ChromeNetworkDelegate to update the task manager with read network usage.
static void OnRawBytesRead(const net::URLRequest& request,
int64_t bytes_read);
+ // This notification will be received on the IO thread from
+ // ChromeNetworkDelegate to update the task manager with sent network usage.
+ static void OnRawBytesSent(const net::URLRequest& request,
+ int64_t bytes_sent);
+
void AddObserver(TaskManagerObserver* observer);
void RemoveObserver(TaskManagerObserver* observer);
@@ -172,11 +177,13 @@
int* out_error_code) const = 0;
// Returns the network usage (in bytes per second) during the current refresh
- // cycle for the task with |task_id|. A value of -1 means no valid value is
- // currently available or that task has never been notified of any network
- // usage.
+ // cycle for the task with |task_id|.
virtual int64_t GetNetworkUsage(TaskId task_id) const = 0;
+ // Returns the network usage during the current lifetime of the task
+ // for the task with |task_id|.
+ virtual int64_t GetCumulativeNetworkUsage(TaskId task_id) const = 0;
+
// Returns the total network usage (in bytes per second) during the current
// refresh cycle for the process on which the task with |task_id| is running.
// This is the sum of all the network usage of the individual tasks (that
@@ -184,6 +191,13 @@
// usage calculation refresh is currently not available.
virtual int64_t GetProcessTotalNetworkUsage(TaskId task_id) const = 0;
+ // Returns the total network usage during the lifetime of the process
+ // on which the task with |task_id| is running.
+ // This is the sum of all the network usage of the individual tasks (that
+ // can be gotten by the above GetTotalNetworkUsage()).
+ virtual int64_t GetCumulativeProcessTotalNetworkUsage(
+ TaskId task_id) const = 0;
+
// Returns the Sqlite used memory (in bytes) for the task with |task_id|.
// A value of -1 means no valid value is currently available.
virtual int64_t GetSqliteMemoryUsed(TaskId task_id) const = 0;
diff --git a/chrome/browser/task_manager/task_manager_tester.cc b/chrome/browser/task_manager/task_manager_tester.cc
index f93a249..25d852a 100644
--- a/chrome/browser/task_manager/task_manager_tester.cc
+++ b/chrome/browser/task_manager/task_manager_tester.cc
@@ -112,6 +112,10 @@
case ColumnSpecifier::MEMORY_STATE:
column_id = IDS_TASK_MANAGER_MEMORY_STATE_COLUMN;
break;
+ case ColumnSpecifier::TOTAL_NETWORK_USE:
+ case ColumnSpecifier::NETWORK_USE:
+ column_id = IDS_TASK_MANAGER_NET_COLUMN;
+ break;
}
model_->ToggleColumnVisibility(column_id);
}
@@ -140,6 +144,13 @@
value = task_manager()->GetIdleWakeupsPerSecond(task_id);
success = true;
break;
+ case ColumnSpecifier::NETWORK_USE:
+ value = task_manager()->GetNetworkUsage(task_id);
+ success = true;
+ case ColumnSpecifier::TOTAL_NETWORK_USE:
+ value = task_manager()->GetCumulativeNetworkUsage(task_id);
+ success = true;
+ break;
}
if (!success)
return 0;
diff --git a/chrome/browser/task_manager/test_task_manager.cc b/chrome/browser/task_manager/test_task_manager.cc
index 5b90af6..23d93ee 100644
--- a/chrome/browser/task_manager/test_task_manager.cc
+++ b/chrome/browser/task_manager/test_task_manager.cc
@@ -135,13 +135,22 @@
}
int64_t TestTaskManager::GetNetworkUsage(TaskId task_id) const {
- return -1;
+ return 0;
}
int64_t TestTaskManager::GetProcessTotalNetworkUsage(TaskId task_id) const {
return -1;
}
+int64_t TestTaskManager::GetCumulativeNetworkUsage(TaskId task_id) const {
+ return 0;
+}
+
+int64_t TestTaskManager::GetCumulativeProcessTotalNetworkUsage(
+ TaskId task_id) const {
+ return 0;
+}
+
int64_t TestTaskManager::GetSqliteMemoryUsed(TaskId task_id) const {
return -1;
}
diff --git a/chrome/browser/task_manager/test_task_manager.h b/chrome/browser/task_manager/test_task_manager.h
index 4af6f95..bca4d0a6 100644
--- a/chrome/browser/task_manager/test_task_manager.h
+++ b/chrome/browser/task_manager/test_task_manager.h
@@ -60,6 +60,8 @@
int* out_error_code) const override;
int64_t GetNetworkUsage(TaskId task_id) const override;
int64_t GetProcessTotalNetworkUsage(TaskId task_id) const override;
+ int64_t GetCumulativeNetworkUsage(TaskId task_id) const override;
+ int64_t GetCumulativeProcessTotalNetworkUsage(TaskId task_id) const override;
int64_t GetSqliteMemoryUsed(TaskId task_id) const override;
bool GetV8Memory(TaskId task_id,
int64_t* allocated,