Only grant permissions to new extensions from sync if they have the expected version
[chromium-blink-merge.git] / chromecast / net / connectivity_checker_impl.cc
blob9a2b14b21ec8f8f3b6064971128fd736adadeb44
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromecast/net/connectivity_checker_impl.h"
7 #include "base/command_line.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "chromecast/net/net_switches.h"
11 #include "net/base/request_priority.h"
12 #include "net/http/http_response_headers.h"
13 #include "net/http/http_response_info.h"
14 #include "net/http/http_status_code.h"
15 #include "net/proxy/proxy_config.h"
16 #include "net/proxy/proxy_config_service_fixed.h"
17 #include "net/socket/ssl_client_socket.h"
18 #include "net/url_request/url_request_context.h"
19 #include "net/url_request/url_request_context_builder.h"
21 namespace chromecast {
23 namespace {
25 // How often connectivity checks are performed in seconds.
26 const unsigned int kConnectivityPeriodSeconds = 1;
28 // Number of consecutive connectivity check errors before status is changed
29 // to offline.
30 const unsigned int kNumErrorsToNotifyOffline = 3;
32 // Request timeout value in seconds.
33 const unsigned int kRequestTimeoutInSeconds = 3;
35 // Default url for connectivity checking.
36 const char kDefaultConnectivityCheckUrl[] =
37 "https://clients3.google.com/generate_204";
39 } // namespace
41 ConnectivityCheckerImpl::ConnectivityCheckerImpl(
42 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
43 : ConnectivityChecker(),
44 task_runner_(task_runner),
45 connected_(false),
46 check_errors_(0) {
47 DCHECK(task_runner_.get());
48 task_runner->PostTask(FROM_HERE,
49 base::Bind(&ConnectivityCheckerImpl::Initialize, this));
52 void ConnectivityCheckerImpl::Initialize() {
53 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
54 base::CommandLine::StringType check_url_str =
55 command_line->GetSwitchValueNative(switches::kConnectivityCheckUrl);
56 connectivity_check_url_.reset(new GURL(
57 check_url_str.empty() ? kDefaultConnectivityCheckUrl : check_url_str));
59 net::URLRequestContextBuilder builder;
60 builder.set_proxy_config_service(make_scoped_ptr(
61 new net::ProxyConfigServiceFixed(net::ProxyConfig::CreateDirect())));
62 builder.DisableHttpCache();
63 url_request_context_ = builder.Build().Pass();
65 net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
66 task_runner_->PostTask(FROM_HERE,
67 base::Bind(&ConnectivityCheckerImpl::Check, this));
70 ConnectivityCheckerImpl::~ConnectivityCheckerImpl() {
71 DCHECK(task_runner_.get());
72 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
73 task_runner_->DeleteSoon(FROM_HERE, url_request_.release());
74 task_runner_->DeleteSoon(FROM_HERE, url_request_context_.release());
77 bool ConnectivityCheckerImpl::Connected() const {
78 return connected_;
81 void ConnectivityCheckerImpl::SetConnected(bool connected) {
82 if (connected_ == connected)
83 return;
85 connected_ = connected;
86 Notify(connected);
87 LOG(INFO) << "Global connection is: " << (connected ? "Up" : "Down");
90 void ConnectivityCheckerImpl::Check() {
91 if (!task_runner_->BelongsToCurrentThread()) {
92 task_runner_->PostTask(FROM_HERE,
93 base::Bind(&ConnectivityCheckerImpl::Check, this));
94 return;
96 DCHECK(url_request_context_.get());
98 // Don't check connectivity if network is offline, because Internet could be
99 // accessible via netifs ignored.
100 if (net::NetworkChangeNotifier::IsOffline())
101 return;
103 // If url_request_ is non-null, there is already a check going on. Don't
104 // start another.
105 if (url_request_.get())
106 return;
108 VLOG(1) << "Connectivity check: url=" << *connectivity_check_url_;
109 url_request_ = url_request_context_->CreateRequest(
110 *connectivity_check_url_, net::MAXIMUM_PRIORITY, this);
111 url_request_->set_method("HEAD");
112 url_request_->Start();
114 timeout_.Reset(base::Bind(&ConnectivityCheckerImpl::OnUrlRequestTimeout,
115 this));
116 base::MessageLoop::current()->PostDelayedTask(
117 FROM_HERE,
118 timeout_.callback(),
119 base::TimeDelta::FromSeconds(kRequestTimeoutInSeconds));
122 void ConnectivityCheckerImpl::OnNetworkChanged(
123 net::NetworkChangeNotifier::ConnectionType type) {
124 VLOG(2) << "OnNetworkChanged " << type;
125 Cancel();
127 if (type == net::NetworkChangeNotifier::CONNECTION_NONE) {
128 SetConnected(false);
129 return;
132 Check();
135 void ConnectivityCheckerImpl::OnResponseStarted(net::URLRequest* request) {
136 timeout_.Cancel();
137 int http_response_code =
138 (request->status().is_success() &&
139 request->response_info().headers.get() != NULL)
140 ? request->response_info().headers->response_code()
141 : net::HTTP_BAD_REQUEST;
143 // Clears resources.
144 url_request_.reset(NULL); // URLRequest::Cancel() is called in destructor.
146 if (http_response_code < 400) {
147 VLOG(1) << "Connectivity check succeeded";
148 check_errors_ = 0;
149 SetConnected(true);
150 return;
152 VLOG(1) << "Connectivity check failed: " << http_response_code;
153 OnUrlRequestError();
156 void ConnectivityCheckerImpl::OnReadCompleted(net::URLRequest* request,
157 int bytes_read) {
158 NOTREACHED();
161 void ConnectivityCheckerImpl::OnSSLCertificateError(
162 net::URLRequest* request,
163 const net::SSLInfo& ssl_info,
164 bool fatal) {
165 LOG(ERROR) << "OnSSLCertificateError: cert_status=" << ssl_info.cert_status;
166 timeout_.Cancel();
167 net::SSLClientSocket::ClearSessionCache();
168 OnUrlRequestError();
171 void ConnectivityCheckerImpl::OnUrlRequestError() {
172 ++check_errors_;
173 if (check_errors_ > kNumErrorsToNotifyOffline) {
174 check_errors_ = kNumErrorsToNotifyOffline;
175 SetConnected(false);
177 url_request_.reset(NULL);
178 // Check again.
179 task_runner_->PostDelayedTask(
180 FROM_HERE, base::Bind(&ConnectivityCheckerImpl::Check, this),
181 base::TimeDelta::FromSeconds(kConnectivityPeriodSeconds));
184 void ConnectivityCheckerImpl::OnUrlRequestTimeout() {
185 LOG(ERROR) << "time out";
186 OnUrlRequestError();
189 void ConnectivityCheckerImpl::Cancel() {
190 if (!url_request_.get())
191 return;
192 VLOG(2) << "Cancel connectivity check in progress";
193 timeout_.Cancel();
194 url_request_.reset(NULL); // URLRequest::Cancel() is called in destructor.
197 } // namespace chromecast