Commit c9b7a5a0 authored by rajendrant's avatar rajendrant Committed by Commit bot

Support for identifying traffic type in data use ascriber

Traffic type will be used in data saver site-breakdown code to ignore
non user initiated traffic.

BUG=718656

Review-Url: https://codereview.chromium.org/2865913002
Cr-Commit-Position: refs/heads/master@{#472293}
parent 7f18c51a
......@@ -85,8 +85,8 @@ ChromeDataUseAscriber::GetOrCreateDataUseRecorderEntry(
DataUseUserData* service = static_cast<DataUseUserData*>(
request->GetUserData(DataUseUserData::kUserDataKey));
if (service) {
DataUseRecorderEntry entry = CreateNewDataUseRecorder(request);
DataUseRecorderEntry entry =
CreateNewDataUseRecorder(request, DataUse::TrafficType::SERVICES);
entry->data_use().set_description(
DataUseUserData::GetServiceNameAsString(service->service_name()));
return entry;
......@@ -127,7 +127,8 @@ ChromeDataUseAscriber::GetOrCreateDataUseRecorderEntry(
content::GlobalRequestID navigation_key =
request_info->GetGlobalRequestID();
DataUseRecorderEntry new_entry = CreateNewDataUseRecorder(request);
DataUseRecorderEntry new_entry =
CreateNewDataUseRecorder(request, DataUse::TrafficType::USER_TRAFFIC);
new_entry->set_main_frame_request_id(navigation_key);
pending_navigation_data_use_map_.insert(
std::make_pair(navigation_key, new_entry));
......@@ -145,7 +146,11 @@ ChromeDataUseAscriber::GetOrCreateDataUseRecorderEntry(
}
// Create a new DataUseRecorder for all other requests.
DataUseRecorderEntry entry = CreateNewDataUseRecorder(request);
DataUseRecorderEntry entry = CreateNewDataUseRecorder(
request,
content::ResourceRequestInfo::OriginatedFromServiceWorker(request)
? DataUse::TrafficType::SERVICE_WORKER
: DataUse::TrafficType::UNKNOWN);
DataUse& data_use = entry->data_use();
data_use.set_url(request->url());
return entry;
......@@ -221,7 +226,8 @@ void ChromeDataUseAscriber::RenderFrameCreated(int render_process_id,
auto frame_iter = main_render_frame_data_use_map_.find(
RenderFrameHostID(render_process_id, render_frame_id));
DCHECK(frame_iter == main_render_frame_data_use_map_.end());
DataUseRecorderEntry entry = CreateNewDataUseRecorder(nullptr);
DataUseRecorderEntry entry =
CreateNewDataUseRecorder(nullptr, DataUse::TrafficType::UNKNOWN);
entry->set_main_frame_id(
RenderFrameHostID(render_process_id, render_frame_id));
main_render_frame_data_use_map_.insert(std::make_pair(
......@@ -284,6 +290,8 @@ void ChromeDataUseAscriber::ReadyToCommitMainFrameNavigation(
// must be removed from frame map, and possibly marked complete and deleted.
if (frame_it != main_render_frame_data_use_map_.end()) {
DataUseRecorderEntry old_frame_entry = frame_it->second;
DataUse::TrafficType old_traffic_type =
old_frame_entry->data_use().traffic_type();
main_render_frame_data_use_map_.erase(frame_it);
if (old_frame_entry->IsDataUseComplete()) {
OnDataUseCompleted(old_frame_entry);
......@@ -292,7 +300,7 @@ void ChromeDataUseAscriber::ReadyToCommitMainFrameNavigation(
// Add a new recorder to the render frame map to replace the deleted one.
DataUseRecorderEntry entry = data_use_recorders_.emplace(
data_use_recorders_.end());
data_use_recorders_.end(), old_traffic_type);
std::pair<int, int> frame_key =
RenderFrameHostID(render_process_id, render_frame_id);
entry->set_main_frame_id(frame_key);
......@@ -380,9 +388,11 @@ ChromeDataUseAscriber::CreateURLRequestClassifier() const {
}
ChromeDataUseAscriber::DataUseRecorderEntry
ChromeDataUseAscriber::CreateNewDataUseRecorder(net::URLRequest* request) {
DataUseRecorderEntry entry = data_use_recorders_.emplace(
data_use_recorders_.end());
ChromeDataUseAscriber::CreateNewDataUseRecorder(
net::URLRequest* request,
DataUse::TrafficType traffic_type) {
DataUseRecorderEntry entry =
data_use_recorders_.emplace(data_use_recorders_.end(), traffic_type);
if (request) {
entry->AddPendingURLRequest(request);
request->SetUserData(
......
......@@ -142,7 +142,9 @@ class ChromeDataUseAscriber : public DataUseAscriber {
void OnDataUseCompleted(DataUseRecorderEntry entry);
DataUseRecorderEntry CreateNewDataUseRecorder(net::URLRequest* request);
DataUseRecorderEntry CreateNewDataUseRecorder(
net::URLRequest* request,
DataUse::TrafficType traffic_type);
bool IsRecorderInPendingNavigationMap(net::URLRequest* request);
......
......@@ -24,6 +24,7 @@ namespace {
int kRenderProcessId = 1;
int kRenderFrameId = 2;
int kRequestId = 3;
void* kNavigationHandle = &kNavigationHandle;
}
namespace data_use_measurement {
......@@ -171,4 +172,46 @@ TEST_F(ChromeDataUseAscriberTest, RenderFrameHostChanged) {
-1);
}
TEST_F(ChromeDataUseAscriberTest, MainFrameNavigation) {
if (content::IsBrowserSideNavigationEnabled())
return;
std::unique_ptr<net::URLRequest> request = CreateNewRequest(
"http://test.com", true, kRequestId, kRenderProcessId, kRenderFrameId);
// Mainframe is created.
ascriber()->RenderFrameCreated(kRenderProcessId, kRenderFrameId, -1, -1);
EXPECT_EQ(1u, recorders().size());
// Request should cause a recorder to be created.
ascriber()->OnBeforeUrlRequest(request.get());
EXPECT_EQ(2u, recorders().size());
// Navigation starts.
ascriber()->DidStartMainFrameNavigation(GURL("http://test.com"),
kRenderProcessId, kRenderFrameId,
kNavigationHandle);
ascriber()->ReadyToCommitMainFrameNavigation(
GURL("http://mobile.test.com"),
content::GlobalRequestID(kRenderProcessId, 0), kRenderProcessId,
kRenderFrameId, false, kNavigationHandle);
// Navigation commit should merge the two data use recorder entries.
EXPECT_EQ(1u, recorders().size());
auto& recorder_entry = recorders().front();
EXPECT_EQ(RenderFrameHostID(kRenderProcessId, kRenderFrameId),
recorder_entry.main_frame_id());
EXPECT_EQ(content::GlobalRequestID(kRenderProcessId, 0),
recorder_entry.main_frame_request_id());
EXPECT_EQ(GURL("http://mobile.test.com"), recorder_entry.data_use().url());
EXPECT_EQ(DataUse::TrafficType::USER_TRAFFIC,
recorder_entry.data_use().traffic_type());
ascriber()->RenderFrameDeleted(kRenderProcessId, kRenderFrameId, -1, -1);
ascriber()->OnUrlRequestDestroyed(request.get());
EXPECT_EQ(0u, recorders().size());
}
} // namespace data_use_measurement
......@@ -7,7 +7,8 @@
namespace data_use_measurement {
ChromeDataUseRecorder::ChromeDataUseRecorder() : main_frame_id_(-1, -1) {
ChromeDataUseRecorder::ChromeDataUseRecorder(DataUse::TrafficType traffic_type)
: DataUseRecorder(traffic_type), main_frame_id_(-1, -1) {
set_page_transition(ui::PAGE_TRANSITION_LAST_CORE + 1);
}
......
......@@ -17,7 +17,7 @@ typedef std::pair<int, int> RenderFrameHostID;
class ChromeDataUseRecorder : public DataUseRecorder {
public:
ChromeDataUseRecorder();
explicit ChromeDataUseRecorder(DataUse::TrafficType traffic_type);
~ChromeDataUseRecorder() override;
RenderFrameHostID main_frame_id() const { return main_frame_id_; }
......
......@@ -6,15 +6,18 @@
namespace data_use_measurement {
DataUse::DataUse() : total_bytes_sent_(0), total_bytes_received_(0) {}
DataUse::DataUse(const DataUse& other) :
total_bytes_sent_(other.total_bytes_sent_),
total_bytes_received_(other.total_bytes_received_) {}
DataUse::DataUse(TrafficType traffic_type)
: traffic_type_(traffic_type),
total_bytes_sent_(0),
total_bytes_received_(0) {}
DataUse::~DataUse() {}
void DataUse::MergeFrom(const DataUse& other) {
// Traffic type need not be same while merging. One of the data use created
// when mainframe is created could have UNKNOWN traffic type, and later merged
// with the data use created for its mainframe request which could be
// USER_TRAFFIC.
total_bytes_sent_ += other.total_bytes_sent_;
total_bytes_received_ += other.total_bytes_received_;
}
......
......@@ -18,8 +18,25 @@ namespace data_use_measurement {
// Class to store total network data used by some entity.
class DataUse {
public:
DataUse();
DataUse(const DataUse& other);
enum class TrafficType {
// Unknown type. URLRequests for arbitrary scheme such as blob, file,
// extensions, chrome URLs fall under this bucket - url/url_constants.cc
// TODO(rajendrant): Record metrics on the distribution of these type. It is
// also possible to remove this UNKNOWN type altogether by skipping the URL
// schemes that do not make use of network.
UNKNOWN,
// User initiated traffic.
USER_TRAFFIC,
// Chrome services.
SERVICES,
// Fetch from ServiceWorker.
SERVICE_WORKER,
};
explicit DataUse(TrafficType traffic_type);
~DataUse();
// Merge data use from another instance.
......@@ -39,14 +56,21 @@ class DataUse {
int64_t total_bytes_sent() const { return total_bytes_sent_; }
TrafficType traffic_type() const { return traffic_type_; }
private:
// TODO(rajendrant): Remove this friend after adding member function to
// increment total sent/received bytes.
friend class DataUseRecorder;
GURL url_;
std::string description_;
const TrafficType traffic_type_;
int64_t total_bytes_sent_;
int64_t total_bytes_received_;
DISALLOW_COPY_AND_ASSIGN(DataUse);
};
} // namespace data_use_measurement
......
......@@ -70,7 +70,7 @@ class TestURLRequestClassifier : public base::SupportsUserData::Data,
class TestDataUseAscriber : public DataUseAscriber {
public:
TestDataUseAscriber() {}
TestDataUseAscriber() : recorder_(DataUse::TrafficType::USER_TRAFFIC) {}
DataUseRecorder* GetOrCreateDataUseRecorder(
net::URLRequest* request) override {
......
......@@ -8,8 +8,8 @@
namespace data_use_measurement {
DataUseRecorder::DataUseRecorder()
: main_url_request_(nullptr), is_visible_(false) {}
DataUseRecorder::DataUseRecorder(DataUse::TrafficType traffic_type)
: main_url_request_(nullptr), data_use_(traffic_type), is_visible_(false) {}
DataUseRecorder::~DataUseRecorder() {}
......
......@@ -25,7 +25,7 @@ namespace data_use_measurement {
// tracked by exactly one DataUseRecorder.
class DataUseRecorder {
public:
DataUseRecorder();
explicit DataUseRecorder(DataUse::TrafficType traffic_type);
virtual ~DataUseRecorder();
// Returns the actual data used by the entity being tracked.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment