OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_ping
back_client.h" | 5 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_ping
back_client.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
| 9 #include "base/bind_helpers.h" |
9 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
10 #include "base/optional.h" | 11 #include "base/optional.h" |
11 #include "base/rand_util.h" | 12 #include "base/rand_util.h" |
| 13 #include "base/threading/thread_task_runner_handle.h" |
12 #include "base/time/time.h" | 14 #include "base/time/time.h" |
13 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data
.h" | 15 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data
.h" |
14 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_page_
load_timing.h" | 16 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_page_
load_timing.h" |
15 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_param
s.h" | 17 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_param
s.h" |
16 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_util.
h" | 18 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_util.
h" |
17 #include "components/data_reduction_proxy/proto/client_config.pb.h" | 19 #include "components/data_reduction_proxy/proto/client_config.pb.h" |
18 #include "components/data_use_measurement/core/data_use_user_data.h" | 20 #include "components/data_use_measurement/core/data_use_user_data.h" |
19 #include "net/base/load_flags.h" | 21 #include "net/base/load_flags.h" |
20 #include "net/nqe/effective_connection_type.h" | 22 #include "net/nqe/effective_connection_type.h" |
21 #include "net/url_request/url_fetcher.h" | 23 #include "net/url_request/url_fetcher.h" |
22 #include "net/url_request/url_request_context_getter.h" | 24 #include "net/url_request/url_request_context_getter.h" |
23 #include "net/url_request/url_request_status.h" | 25 #include "net/url_request/url_request_status.h" |
24 #include "url/gurl.h" | 26 #include "url/gurl.h" |
25 | 27 |
26 namespace data_reduction_proxy { | 28 namespace data_reduction_proxy { |
27 | 29 |
28 namespace { | 30 namespace { |
29 | 31 |
30 static const char kHistogramSucceeded[] = | 32 static const char kHistogramSucceeded[] = |
31 "DataReductionProxy.Pingback.Succeeded"; | 33 "DataReductionProxy.Pingback.Succeeded"; |
32 static const char kHistogramAttempted[] = | 34 static const char kHistogramAttempted[] = |
33 "DataReductionProxy.Pingback.Attempted"; | 35 "DataReductionProxy.Pingback.Attempted"; |
34 | 36 |
35 // Adds the relevant information to |request| for this page load based on page | 37 // Adds the relevant information to |request| for this page load based on page |
36 // timing and data reduction proxy state. | 38 // timing and data reduction proxy state. |opt_out_page_id| represents an opt |
| 39 // out for a given load. If |opt_out_page_id| is empty, there was no opt out. If |
| 40 // |opt_out_page_id| does not match the page id in |request_data|, it means the |
| 41 // navigation for |opt_out_page_id| is old and was not originally tracked by the |
| 42 // metrics observer when the opt out occured and the current page load did not |
| 43 // see an opt out. |
37 void AddDataToPageloadMetrics(const DataReductionProxyData& request_data, | 44 void AddDataToPageloadMetrics(const DataReductionProxyData& request_data, |
38 const DataReductionProxyPageLoadTiming& timing, | 45 const DataReductionProxyPageLoadTiming& timing, |
39 PageloadMetrics* request) { | 46 PageloadMetrics* request, |
| 47 base::Optional<uint64_t> opt_out_page_id) { |
40 request->set_session_key(request_data.session_key()); | 48 request->set_session_key(request_data.session_key()); |
41 // For the timing events, any of them could be zero. Fill the message as a | 49 // For the timing events, any of them could be zero. Fill the message as a |
42 // best effort. | 50 // best effort. |
43 request->set_allocated_first_request_time( | 51 request->set_allocated_first_request_time( |
44 protobuf_parser::CreateTimestampFromTime(timing.navigation_start) | 52 protobuf_parser::CreateTimestampFromTime(timing.navigation_start) |
45 .release()); | 53 .release()); |
46 if (request_data.request_url().is_valid()) | 54 if (request_data.request_url().is_valid()) |
47 request->set_first_request_url(request_data.request_url().spec()); | 55 request->set_first_request_url(request_data.request_url().spec()); |
48 if (timing.first_contentful_paint) { | 56 if (timing.first_contentful_paint) { |
49 request->set_allocated_time_to_first_contentful_paint( | 57 request->set_allocated_time_to_first_contentful_paint( |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 | 97 |
90 request->set_effective_connection_type( | 98 request->set_effective_connection_type( |
91 protobuf_parser::ProtoEffectiveConnectionTypeFromEffectiveConnectionType( | 99 protobuf_parser::ProtoEffectiveConnectionTypeFromEffectiveConnectionType( |
92 request_data.effective_connection_type())); | 100 request_data.effective_connection_type())); |
93 request->set_compressed_page_size_bytes(timing.network_bytes); | 101 request->set_compressed_page_size_bytes(timing.network_bytes); |
94 request->set_original_page_size_bytes(timing.original_network_bytes); | 102 request->set_original_page_size_bytes(timing.original_network_bytes); |
95 | 103 |
96 if (request_data.page_id()) { | 104 if (request_data.page_id()) { |
97 request->set_page_id(request_data.page_id().value()); | 105 request->set_page_id(request_data.page_id().value()); |
98 } | 106 } |
| 107 |
| 108 bool was_preview_shown = false; |
| 109 if (request_data.lofi_received()) { |
| 110 request->set_previews_type(PageloadMetrics_PreviewsType_LOFI); |
| 111 was_preview_shown = true; |
| 112 } else if (request_data.lite_page_received()) { |
| 113 request->set_previews_type(PageloadMetrics_PreviewsType_LITE_PAGE); |
| 114 was_preview_shown = true; |
| 115 } else { |
| 116 request->set_previews_type(PageloadMetrics_PreviewsType_NONE); |
| 117 } |
| 118 |
| 119 if (!was_preview_shown || timing.app_background_occured) { |
| 120 request->set_previews_opt_out(PageloadMetrics_PreviewsOptOut_UNKNOWN); |
| 121 return; |
| 122 } |
| 123 |
| 124 if (opt_out_page_id && request_data.page_id() && |
| 125 opt_out_page_id.value() == request_data.page_id().value()) { |
| 126 request->set_previews_opt_out(PageloadMetrics_PreviewsOptOut_OPT_OUT); |
| 127 return; |
| 128 } |
| 129 request->set_previews_opt_out(PageloadMetrics_PreviewsOptOut_NON_OPT_OUT); |
99 } | 130 } |
100 | 131 |
101 // Adds |current_time| as the metrics sent time to |request_data|, and returns | 132 // Adds |current_time| as the metrics sent time to |request_data|, and returns |
102 // the serialized request. | 133 // the serialized request. |
103 std::string AddTimeAndSerializeRequest( | 134 std::string AddTimeAndSerializeRequest( |
104 RecordPageloadMetricsRequest* request_data, | 135 RecordPageloadMetricsRequest* request_data, |
105 base::Time current_time) { | 136 base::Time current_time) { |
106 request_data->set_allocated_metrics_sent_time( | 137 request_data->set_allocated_metrics_sent_time( |
107 protobuf_parser::CreateTimestampFromTime(current_time).release()); | 138 protobuf_parser::CreateTimestampFromTime(current_time).release()); |
108 std::string serialized_request; | 139 std::string serialized_request; |
109 request_data->SerializeToString(&serialized_request); | 140 request_data->SerializeToString(&serialized_request); |
110 return serialized_request; | 141 return serialized_request; |
111 } | 142 } |
112 | 143 |
113 } // namespace | 144 } // namespace |
114 | 145 |
115 DataReductionProxyPingbackClient::DataReductionProxyPingbackClient( | 146 DataReductionProxyPingbackClient::DataReductionProxyPingbackClient( |
116 net::URLRequestContextGetter* url_request_context) | 147 net::URLRequestContextGetter* url_request_context) |
117 : url_request_context_(url_request_context), | 148 : url_request_context_(url_request_context), |
118 pingback_url_(util::AddApiKeyToUrl(params::GetPingbackURL())), | 149 pingback_url_(util::AddApiKeyToUrl(params::GetPingbackURL())), |
119 pingback_reporting_fraction_(0.0) {} | 150 pingback_reporting_fraction_(0.0) {} |
120 | 151 |
121 DataReductionProxyPingbackClient::~DataReductionProxyPingbackClient() { | 152 DataReductionProxyPingbackClient::~DataReductionProxyPingbackClient() { |
| 153 DCHECK(tab_page_id_map_.empty()); |
122 DCHECK(thread_checker_.CalledOnValidThread()); | 154 DCHECK(thread_checker_.CalledOnValidThread()); |
123 } | 155 } |
124 | 156 |
125 void DataReductionProxyPingbackClient::OnURLFetchComplete( | 157 void DataReductionProxyPingbackClient::OnURLFetchComplete( |
126 const net::URLFetcher* source) { | 158 const net::URLFetcher* source) { |
127 DCHECK(thread_checker_.CalledOnValidThread()); | 159 DCHECK(thread_checker_.CalledOnValidThread()); |
128 DCHECK(source == current_fetcher_.get()); | 160 DCHECK(source == current_fetcher_.get()); |
129 UMA_HISTOGRAM_BOOLEAN(kHistogramSucceeded, source->GetStatus().is_success()); | 161 UMA_HISTOGRAM_BOOLEAN(kHistogramSucceeded, source->GetStatus().is_success()); |
130 current_fetcher_.reset(); | 162 current_fetcher_.reset(); |
131 if (metrics_request_.pageloads_size() > 0) { | 163 if (metrics_request_.pageloads_size() > 0) { |
132 CreateFetcherForDataAndStart(); | 164 CreateFetcherForDataAndStart(); |
133 } | 165 } |
134 } | 166 } |
135 | 167 |
136 void DataReductionProxyPingbackClient::SendPingback( | 168 void DataReductionProxyPingbackClient::SendPingback( |
137 const DataReductionProxyData& request_data, | 169 const DataReductionProxyData& request_data, |
138 const DataReductionProxyPageLoadTiming& timing) { | 170 const DataReductionProxyPageLoadTiming& timing, |
| 171 const void* tab_identifier_key) { |
139 DCHECK(thread_checker_.CalledOnValidThread()); | 172 DCHECK(thread_checker_.CalledOnValidThread()); |
140 bool send_pingback = ShouldSendPingback(); | 173 bool send_pingback = ShouldSendPingback(); |
141 UMA_HISTOGRAM_BOOLEAN(kHistogramAttempted, send_pingback); | 174 UMA_HISTOGRAM_BOOLEAN(kHistogramAttempted, send_pingback); |
142 if (!send_pingback) | 175 if (!send_pingback) |
143 return; | 176 return; |
| 177 |
| 178 auto page_id_iter = tab_page_id_map_.find(tab_identifier_key); |
| 179 base::Optional<uint64_t> opt_out_page_id; |
| 180 if (page_id_iter != tab_page_id_map_.end()) { |
| 181 opt_out_page_id = page_id_iter->second; |
| 182 tab_page_id_map_.erase(page_id_iter); |
| 183 } |
| 184 |
144 PageloadMetrics* pageload_metrics = metrics_request_.add_pageloads(); | 185 PageloadMetrics* pageload_metrics = metrics_request_.add_pageloads(); |
145 AddDataToPageloadMetrics(request_data, timing, pageload_metrics); | 186 AddDataToPageloadMetrics(request_data, timing, pageload_metrics, |
| 187 opt_out_page_id); |
146 if (current_fetcher_.get()) | 188 if (current_fetcher_.get()) |
147 return; | 189 return; |
148 DCHECK_EQ(1, metrics_request_.pageloads_size()); | 190 DCHECK_EQ(1, metrics_request_.pageloads_size()); |
149 CreateFetcherForDataAndStart(); | 191 CreateFetcherForDataAndStart(); |
150 } | 192 } |
151 | 193 |
152 void DataReductionProxyPingbackClient::CreateFetcherForDataAndStart() { | 194 void DataReductionProxyPingbackClient::CreateFetcherForDataAndStart() { |
153 DCHECK(!current_fetcher_); | 195 DCHECK(!current_fetcher_); |
154 DCHECK_GE(metrics_request_.pageloads_size(), 1); | 196 DCHECK_GE(metrics_request_.pageloads_size(), 1); |
155 std::string serialized_request = | 197 std::string serialized_request = |
(...skipping 28 matching lines...) Expand all Loading... |
184 } | 226 } |
185 | 227 |
186 void DataReductionProxyPingbackClient::SetPingbackReportingFraction( | 228 void DataReductionProxyPingbackClient::SetPingbackReportingFraction( |
187 float pingback_reporting_fraction) { | 229 float pingback_reporting_fraction) { |
188 DCHECK(thread_checker_.CalledOnValidThread()); | 230 DCHECK(thread_checker_.CalledOnValidThread()); |
189 DCHECK_LE(0.0f, pingback_reporting_fraction); | 231 DCHECK_LE(0.0f, pingback_reporting_fraction); |
190 DCHECK_GE(1.0f, pingback_reporting_fraction); | 232 DCHECK_GE(1.0f, pingback_reporting_fraction); |
191 pingback_reporting_fraction_ = pingback_reporting_fraction; | 233 pingback_reporting_fraction_ = pingback_reporting_fraction; |
192 } | 234 } |
193 | 235 |
| 236 void DataReductionProxyPingbackClient::AddOptOut(const void* tab_identifier_key, |
| 237 uint64_t page_id) { |
| 238 tab_page_id_map_[tab_identifier_key] = page_id; |
| 239 } |
| 240 |
| 241 void DataReductionProxyPingbackClient::ClearTabKeySync( |
| 242 const void* tab_identifier_key) { |
| 243 tab_page_id_map_.erase(tab_identifier_key); |
| 244 } |
| 245 |
| 246 void DataReductionProxyPingbackClient::ClearTabKeyAsync( |
| 247 const void* tab_identifier_key) { |
| 248 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 249 FROM_HERE, base::Bind(&DataReductionProxyPingbackClient::ClearTabKeySync, |
| 250 base::Unretained(this), tab_identifier_key)); |
| 251 } |
| 252 |
| 253 size_t DataReductionProxyPingbackClient::PendingTabLoadsForTesting() const { |
| 254 return tab_page_id_map_.size(); |
| 255 } |
| 256 |
194 } // namespace data_reduction_proxy | 257 } // namespace data_reduction_proxy |
OLD | NEW |