| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/domain_reliability/monitor.h" | 5 #include "components/domain_reliability/monitor.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/message_loop/message_loop.h" | |
| 10 #include "base/single_thread_task_runner.h" | 9 #include "base/single_thread_task_runner.h" |
| 11 #include "base/task_runner.h" | 10 #include "base/task_runner.h" |
| 12 #include "base/threading/thread_checker.h" | |
| 13 #include "base/time/time.h" | 11 #include "base/time/time.h" |
| 14 #include "components/domain_reliability/baked_in_configs.h" | 12 #include "components/domain_reliability/baked_in_configs.h" |
| 15 #include "net/base/load_flags.h" | 13 #include "net/base/load_flags.h" |
| 16 #include "net/http/http_response_headers.h" | 14 #include "net/http/http_response_headers.h" |
| 17 #include "net/url_request/url_request.h" | 15 #include "net/url_request/url_request.h" |
| 18 #include "net/url_request/url_request_context.h" | 16 #include "net/url_request/url_request_context.h" |
| 19 #include "net/url_request/url_request_context_getter.h" | 17 #include "net/url_request/url_request_context_getter.h" |
| 20 | 18 |
| 21 namespace domain_reliability { | 19 namespace domain_reliability { |
| 22 | 20 |
| 23 DomainReliabilityMonitor::DomainReliabilityMonitor( | 21 DomainReliabilityMonitor::DomainReliabilityMonitor( |
| 24 const std::string& upload_reporter_string) | 22 const std::string& upload_reporter_string, |
| 23 scoped_refptr<base::SingleThreadTaskRunner> pref_thread, |
| 24 scoped_refptr<base::SingleThreadTaskRunner> network_thread, |
| 25 PrefService* local_state_pref_service, |
| 26 const char* reporting_pref_name) |
| 25 : time_(new ActualTime()), | 27 : time_(new ActualTime()), |
| 26 upload_reporter_string_(upload_reporter_string), | 28 upload_reporter_string_(upload_reporter_string), |
| 27 scheduler_params_( | 29 scheduler_params_( |
| 28 DomainReliabilityScheduler::Params::GetFromFieldTrialsOrDefaults()), | 30 DomainReliabilityScheduler::Params::GetFromFieldTrialsOrDefaults()), |
| 29 dispatcher_(time_.get()), | 31 dispatcher_(time_.get()), |
| 30 weak_factory_(this) {} | 32 pref_task_runner_(pref_thread), |
| 33 network_task_runner_(network_thread), |
| 34 moved_to_network_thread_(false), |
| 35 weak_factory_(this) { |
| 36 DCHECK(OnPrefThread()); |
| 37 InitReportingPref(local_state_pref_service, reporting_pref_name); |
| 38 } |
| 31 | 39 |
| 32 DomainReliabilityMonitor::DomainReliabilityMonitor( | 40 DomainReliabilityMonitor::DomainReliabilityMonitor( |
| 33 const std::string& upload_reporter_string, | 41 const std::string& upload_reporter_string, |
| 42 scoped_refptr<base::SingleThreadTaskRunner> pref_thread, |
| 43 scoped_refptr<base::SingleThreadTaskRunner> network_thread, |
| 44 PrefService* local_state_pref_service, |
| 45 const char* reporting_pref_name, |
| 34 scoped_ptr<MockableTime> time) | 46 scoped_ptr<MockableTime> time) |
| 35 : time_(time.Pass()), | 47 : time_(time.Pass()), |
| 36 upload_reporter_string_(upload_reporter_string), | 48 upload_reporter_string_(upload_reporter_string), |
| 37 scheduler_params_( | 49 scheduler_params_( |
| 38 DomainReliabilityScheduler::Params::GetFromFieldTrialsOrDefaults()), | 50 DomainReliabilityScheduler::Params::GetFromFieldTrialsOrDefaults()), |
| 39 dispatcher_(time_.get()), | 51 dispatcher_(time_.get()), |
| 40 weak_factory_(this) {} | 52 pref_task_runner_(pref_thread), |
| 53 network_task_runner_(network_thread), |
| 54 moved_to_network_thread_(false), |
| 55 weak_factory_(this) { |
| 56 DCHECK(OnPrefThread()); |
| 57 InitReportingPref(local_state_pref_service, reporting_pref_name); |
| 58 } |
| 41 | 59 |
| 42 DomainReliabilityMonitor::~DomainReliabilityMonitor() { | 60 DomainReliabilityMonitor::~DomainReliabilityMonitor() { |
| 61 if (moved_to_network_thread_) |
| 62 DCHECK(OnNetworkThread()); |
| 63 else |
| 64 DCHECK(OnPrefThread()); |
| 65 |
| 43 ClearContexts(); | 66 ClearContexts(); |
| 44 } | 67 } |
| 45 | 68 |
| 46 void DomainReliabilityMonitor::Init( | 69 void DomainReliabilityMonitor::MoveToNetworkThread() { |
| 47 net::URLRequestContext* url_request_context, | 70 DCHECK(OnPrefThread()); |
| 48 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) { | 71 DCHECK(!moved_to_network_thread_); |
| 49 DCHECK(!thread_checker_); | 72 |
| 73 reporting_pref_.MoveToThread(network_task_runner_); |
| 74 moved_to_network_thread_ = true; |
| 75 } |
| 76 |
| 77 void DomainReliabilityMonitor::DestroyReportingPref() { |
| 78 DCHECK(OnPrefThread()); |
| 79 |
| 80 reporting_pref_.Destroy(); |
| 81 } |
| 82 |
| 83 void DomainReliabilityMonitor::InitURLRequestContext( |
| 84 net::URLRequestContext* url_request_context) { |
| 85 DCHECK(OnNetworkThread()); |
| 86 DCHECK(moved_to_network_thread_); |
| 50 | 87 |
| 51 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = | 88 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = |
| 52 new net::TrivialURLRequestContextGetter(url_request_context, | 89 new net::TrivialURLRequestContextGetter(url_request_context, |
| 53 task_runner); | 90 network_task_runner_); |
| 54 Init(url_request_context_getter); | 91 InitURLRequestContext(url_request_context_getter); |
| 55 } | 92 } |
| 56 | 93 |
| 57 void DomainReliabilityMonitor::Init( | 94 void DomainReliabilityMonitor::InitURLRequestContext( |
| 58 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) { | 95 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) { |
| 59 DCHECK(!thread_checker_); | 96 DCHECK(OnNetworkThread()); |
| 97 DCHECK(moved_to_network_thread_); |
| 60 | 98 |
| 99 // Make sure the URLRequestContext actually lives on what was declared to be |
| 100 // the network thread. |
| 61 DCHECK(url_request_context_getter->GetNetworkTaskRunner()-> | 101 DCHECK(url_request_context_getter->GetNetworkTaskRunner()-> |
| 62 RunsTasksOnCurrentThread()); | 102 RunsTasksOnCurrentThread()); |
| 63 | 103 |
| 64 uploader_ = DomainReliabilityUploader::Create(url_request_context_getter); | 104 uploader_ = DomainReliabilityUploader::Create(url_request_context_getter); |
| 65 thread_checker_.reset(new base::ThreadChecker()); | 105 // Make sure the uploader is sending or discarding uploads according to pref. |
| 106 OnReportingPrefChanged(); |
| 66 } | 107 } |
| 67 | 108 |
| 68 void DomainReliabilityMonitor::AddBakedInConfigs() { | 109 void DomainReliabilityMonitor::AddBakedInConfigs() { |
| 69 DCHECK(thread_checker_ && thread_checker_->CalledOnValidThread()); | 110 DCHECK(OnNetworkThread()); |
| 111 |
| 70 base::Time now = base::Time::Now(); | 112 base::Time now = base::Time::Now(); |
| 71 for (size_t i = 0; kBakedInJsonConfigs[i]; ++i) { | 113 for (size_t i = 0; kBakedInJsonConfigs[i]; ++i) { |
| 72 std::string json(kBakedInJsonConfigs[i]); | 114 std::string json(kBakedInJsonConfigs[i]); |
| 73 scoped_ptr<const DomainReliabilityConfig> config = | 115 scoped_ptr<const DomainReliabilityConfig> config = |
| 74 DomainReliabilityConfig::FromJSON(json); | 116 DomainReliabilityConfig::FromJSON(json); |
| 75 if (config && config->IsExpired(now)) { | 117 if (config && config->IsExpired(now)) { |
| 76 LOG(WARNING) << "Baked-in Domain Reliability config for " | 118 LOG(WARNING) << "Baked-in Domain Reliability config for " |
| 77 << config->domain << " is expired."; | 119 << config->domain << " is expired."; |
| 78 continue; | 120 continue; |
| 79 } | 121 } |
| 80 AddContext(config.Pass()); | 122 AddContext(config.Pass()); |
| 81 } | 123 } |
| 82 } | 124 } |
| 83 | 125 |
| 84 void DomainReliabilityMonitor::OnBeforeRedirect(net::URLRequest* request) { | 126 void DomainReliabilityMonitor::OnBeforeRedirect(net::URLRequest* request) { |
| 85 DCHECK(thread_checker_ && thread_checker_->CalledOnValidThread()); | 127 DCHECK(OnNetworkThread()); |
| 128 |
| 86 // Record the redirect itself in addition to the final request. | 129 // Record the redirect itself in addition to the final request. |
| 87 OnRequestLegComplete(RequestInfo(*request)); | 130 OnRequestLegComplete(RequestInfo(*request)); |
| 88 } | 131 } |
| 89 | 132 |
| 90 void DomainReliabilityMonitor::OnCompleted(net::URLRequest* request, | 133 void DomainReliabilityMonitor::OnCompleted(net::URLRequest* request, |
| 91 bool started) { | 134 bool started) { |
| 92 DCHECK(thread_checker_ && thread_checker_->CalledOnValidThread()); | 135 DCHECK(OnNetworkThread()); |
| 136 |
| 93 if (!started) | 137 if (!started) |
| 94 return; | 138 return; |
| 95 RequestInfo request_info(*request); | 139 RequestInfo request_info(*request); |
| 96 if (request_info.AccessedNetwork()) { | 140 if (request_info.AccessedNetwork()) { |
| 97 OnRequestLegComplete(request_info); | 141 OnRequestLegComplete(request_info); |
| 98 // A request was just using the network, so now is a good time to run any | 142 // A request was just using the network, so now is a good time to run any |
| 99 // pending and eligible uploads. | 143 // pending and eligible uploads. |
| 100 dispatcher_.RunEligibleTasks(); | 144 dispatcher_.RunEligibleTasks(); |
| 101 } | 145 } |
| 102 } | 146 } |
| 103 | 147 |
| 104 void DomainReliabilityMonitor::ClearBrowsingData( | 148 void DomainReliabilityMonitor::ClearBrowsingData( |
| 105 DomainReliabilityClearMode mode) { | 149 DomainReliabilityClearMode mode) { |
| 106 DCHECK(thread_checker_ && thread_checker_->CalledOnValidThread()); | 150 DCHECK(OnNetworkThread()); |
| 107 | 151 |
| 108 switch (mode) { | 152 switch (mode) { |
| 109 case CLEAR_BEACONS: { | 153 case CLEAR_BEACONS: { |
| 110 ContextMap::const_iterator it; | 154 ContextMap::const_iterator it; |
| 111 for (it = contexts_.begin(); it != contexts_.end(); ++it) | 155 for (it = contexts_.begin(); it != contexts_.end(); ++it) |
| 112 it->second->ClearBeacons(); | 156 it->second->ClearBeacons(); |
| 113 break; | 157 break; |
| 114 }; | 158 }; |
| 115 case CLEAR_CONTEXTS: | 159 case CLEAR_CONTEXTS: |
| 116 ClearContexts(); | 160 ClearContexts(); |
| 117 break; | 161 break; |
| 118 case MAX_CLEAR_MODE: | 162 case MAX_CLEAR_MODE: |
| 119 NOTREACHED(); | 163 NOTREACHED(); |
| 120 } | 164 } |
| 121 } | 165 } |
| 122 | 166 |
| 123 scoped_ptr<base::Value> DomainReliabilityMonitor::GetWebUIData() const { | 167 scoped_ptr<base::Value> DomainReliabilityMonitor::GetWebUIData() const { |
| 168 DCHECK(OnNetworkThread()); |
| 169 |
| 124 base::ListValue* contexts_value = new base::ListValue(); | 170 base::ListValue* contexts_value = new base::ListValue(); |
| 125 for (ContextMap::const_iterator it = contexts_.begin(); | 171 for (ContextMap::const_iterator it = contexts_.begin(); |
| 126 it != contexts_.end(); | 172 it != contexts_.end(); |
| 127 ++it) { | 173 ++it) { |
| 128 contexts_value->Append(it->second->GetWebUIData().release()); | 174 contexts_value->Append(it->second->GetWebUIData().release()); |
| 129 } | 175 } |
| 130 | 176 |
| 131 base::DictionaryValue* data_value = new base::DictionaryValue(); | 177 base::DictionaryValue* data_value = new base::DictionaryValue(); |
| 132 data_value->Set("contexts", contexts_value); | 178 data_value->Set("contexts", contexts_value); |
| 133 | 179 |
| 134 return scoped_ptr<base::Value>(data_value); | 180 return scoped_ptr<base::Value>(data_value); |
| 135 } | 181 } |
| 136 | 182 |
| 137 DomainReliabilityContext* DomainReliabilityMonitor::AddContextForTesting( | 183 DomainReliabilityContext* DomainReliabilityMonitor::AddContextForTesting( |
| 138 scoped_ptr<const DomainReliabilityConfig> config) { | 184 scoped_ptr<const DomainReliabilityConfig> config) { |
| 139 DCHECK(thread_checker_ && thread_checker_->CalledOnValidThread()); | 185 DCHECK(OnNetworkThread()); |
| 186 |
| 140 return AddContext(config.Pass()); | 187 return AddContext(config.Pass()); |
| 141 } | 188 } |
| 142 | 189 |
| 143 DomainReliabilityMonitor::RequestInfo::RequestInfo() {} | 190 DomainReliabilityMonitor::RequestInfo::RequestInfo() {} |
| 144 | 191 |
| 145 DomainReliabilityMonitor::RequestInfo::RequestInfo( | 192 DomainReliabilityMonitor::RequestInfo::RequestInfo( |
| 146 const net::URLRequest& request) | 193 const net::URLRequest& request) |
| 147 : url(request.url()), | 194 : url(request.url()), |
| 148 status(request.status()), | 195 status(request.status()), |
| 149 response_info(request.response_info()), | 196 response_info(request.response_info()), |
| 150 load_flags(request.load_flags()), | 197 load_flags(request.load_flags()), |
| 151 is_upload(DomainReliabilityUploader::URLRequestIsUpload(request)) { | 198 is_upload(DomainReliabilityUploader::URLRequestIsUpload(request)) { |
| 152 request.GetLoadTimingInfo(&load_timing_info); | 199 request.GetLoadTimingInfo(&load_timing_info); |
| 153 } | 200 } |
| 154 | 201 |
| 155 DomainReliabilityMonitor::RequestInfo::~RequestInfo() {} | 202 DomainReliabilityMonitor::RequestInfo::~RequestInfo() {} |
| 156 | 203 |
| 157 bool DomainReliabilityMonitor::RequestInfo::AccessedNetwork() const { | 204 bool DomainReliabilityMonitor::RequestInfo::AccessedNetwork() const { |
| 158 return status.status() != net::URLRequestStatus::CANCELED && | 205 return status.status() != net::URLRequestStatus::CANCELED && |
| 159 response_info.network_accessed; | 206 response_info.network_accessed; |
| 160 } | 207 } |
| 161 | 208 |
| 162 DomainReliabilityContext* DomainReliabilityMonitor::AddContext( | 209 DomainReliabilityContext* DomainReliabilityMonitor::AddContext( |
| 163 scoped_ptr<const DomainReliabilityConfig> config) { | 210 scoped_ptr<const DomainReliabilityConfig> config) { |
| 211 DCHECK(OnNetworkThread()); |
| 164 DCHECK(config); | 212 DCHECK(config); |
| 165 DCHECK(config->IsValid()); | 213 DCHECK(config->IsValid()); |
| 166 | 214 |
| 167 // Grab a copy of the domain before transferring ownership of |config|. | 215 // Grab a copy of the domain before transferring ownership of |config|. |
| 168 std::string domain = config->domain; | 216 std::string domain = config->domain; |
| 169 | 217 |
| 170 DomainReliabilityContext* context = | 218 DomainReliabilityContext* context = |
| 171 new DomainReliabilityContext(time_.get(), | 219 new DomainReliabilityContext(time_.get(), |
| 172 scheduler_params_, | 220 scheduler_params_, |
| 173 upload_reporter_string_, | 221 upload_reporter_string_, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 beacon.server_ip.clear(); | 278 beacon.server_ip.clear(); |
| 231 beacon.protocol = GetDomainReliabilityProtocol( | 279 beacon.protocol = GetDomainReliabilityProtocol( |
| 232 request.response_info.connection_info, | 280 request.response_info.connection_info, |
| 233 request.response_info.ssl_info.is_valid()); | 281 request.response_info.ssl_info.is_valid()); |
| 234 beacon.http_response_code = response_code; | 282 beacon.http_response_code = response_code; |
| 235 beacon.start_time = request.load_timing_info.request_start; | 283 beacon.start_time = request.load_timing_info.request_start; |
| 236 beacon.elapsed = time_->NowTicks() - beacon.start_time; | 284 beacon.elapsed = time_->NowTicks() - beacon.start_time; |
| 237 context->OnBeacon(request.url, beacon); | 285 context->OnBeacon(request.url, beacon); |
| 238 } | 286 } |
| 239 | 287 |
| 288 void DomainReliabilityMonitor::InitReportingPref( |
| 289 PrefService* local_state_pref_service, |
| 290 const char* reporting_pref_name) { |
| 291 reporting_pref_.Init( |
| 292 reporting_pref_name, |
| 293 local_state_pref_service, |
| 294 base::Bind(&DomainReliabilityMonitor::OnReportingPrefChanged, |
| 295 base::Unretained(this))); |
| 296 } |
| 297 |
| 298 void DomainReliabilityMonitor::OnReportingPrefChanged() { |
| 299 DCHECK(OnNetworkThread()); |
| 300 |
| 301 // When metrics reporting is disabled, discard Domain Reliability uploads. |
| 302 if (uploader_) |
| 303 uploader_->set_discard_uploads(!*reporting_pref_); |
| 304 } |
| 305 |
| 240 // TODO(ttuttle): Keep a separate wildcard_contexts_ map to avoid having to | 306 // TODO(ttuttle): Keep a separate wildcard_contexts_ map to avoid having to |
| 241 // prepend '*.' to domains. | 307 // prepend '*.' to domains. |
| 242 DomainReliabilityContext* DomainReliabilityMonitor::GetContextForHost( | 308 DomainReliabilityContext* DomainReliabilityMonitor::GetContextForHost( |
| 243 const std::string& host) const { | 309 const std::string& host) const { |
| 310 DCHECK(OnNetworkThread()); |
| 311 |
| 244 ContextMap::const_iterator context_it; | 312 ContextMap::const_iterator context_it; |
| 245 | 313 |
| 246 context_it = contexts_.find(host); | 314 context_it = contexts_.find(host); |
| 247 if (context_it != contexts_.end()) | 315 if (context_it != contexts_.end()) |
| 248 return context_it->second; | 316 return context_it->second; |
| 249 | 317 |
| 250 std::string host_with_asterisk = "*." + host; | 318 std::string host_with_asterisk = "*." + host; |
| 251 context_it = contexts_.find(host_with_asterisk); | 319 context_it = contexts_.find(host_with_asterisk); |
| 252 if (context_it != contexts_.end()) | 320 if (context_it != contexts_.end()) |
| 253 return context_it->second; | 321 return context_it->second; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 265 | 333 |
| 266 return NULL; | 334 return NULL; |
| 267 } | 335 } |
| 268 | 336 |
| 269 base::WeakPtr<DomainReliabilityMonitor> | 337 base::WeakPtr<DomainReliabilityMonitor> |
| 270 DomainReliabilityMonitor::MakeWeakPtr() { | 338 DomainReliabilityMonitor::MakeWeakPtr() { |
| 271 return weak_factory_.GetWeakPtr(); | 339 return weak_factory_.GetWeakPtr(); |
| 272 } | 340 } |
| 273 | 341 |
| 274 } // namespace domain_reliability | 342 } // namespace domain_reliability |
| OLD | NEW |