Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: chromecast/net/connectivity_checker.cc

Issue 925183003: [Chromecast] Add connectivity checking for Chromecast. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "chromecast/net/connectivity_checker.h"
6
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/url_request/url_request_context.h"
18 #include "net/url_request/url_request_context_builder.h"
19
20 namespace chromecast {
21
22 namespace {
23
24 // How often we perform connectivity checks in seconds
gunsch 2015/02/20 01:56:03 nit: avoid first-person references in comments, he
derekjchow1 2015/02/20 02:24:16 Done.
25 const unsigned int kConnectivityPeriodSeconds = 1;
26
27 // Number of consecutive bad responses we receive before we change connectivity
28 // to offline
29 const unsigned int kNumBadResponses = 3;
30
31 // Default url for connectivity checking.
32 const char kDefaultConnectivityCheckUrl[] =
33 "https://clients3.google.com/generate_204";
34
35 } // namespace
36
37 ConnectivityChecker::ConnectivityChecker(
38 const scoped_refptr<base::MessageLoopProxy>& loop_proxy)
39 : connectivity_observer_list_(
40 new ObserverListThreadSafe<ConnectivityObserver>()),
41 loop_proxy_(loop_proxy),
42 connected_(false),
43 bad_responses_(0) {
44 DCHECK(loop_proxy_.get());
45 loop_proxy->PostTask(FROM_HERE,
46 base::Bind(&ConnectivityChecker::Initialize, this));
47 }
48
49 void ConnectivityChecker::Initialize() {
50 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
51 base::CommandLine::StringType check_url_str =
52 command_line->GetSwitchValueNative(switches::kConnectivityCheckUrl);
53 connectivity_check_url_.reset(new GURL(
54 check_url_str.empty() ? kDefaultConnectivityCheckUrl : check_url_str));
55
56 net::URLRequestContextBuilder builder;
57 builder.set_proxy_config_service(
58 new net::ProxyConfigServiceFixed(net::ProxyConfig::CreateDirect()));
59 builder.DisableHttpCache();
60 url_request_context_.reset(builder.Build());
61
62 net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
63 if (!net::NetworkChangeNotifier::IsOffline()) {
64 loop_proxy_->PostTask(FROM_HERE,
65 base::Bind(&ConnectivityChecker::Check, this));
66 }
67 }
68
69 ConnectivityChecker::~ConnectivityChecker() {
70 DCHECK(loop_proxy_.get());
71 loop_proxy_->DeleteSoon(FROM_HERE, url_request_context_.release());
72 }
73
74 void ConnectivityChecker::AddConnectivityObserver(
75 ConnectivityObserver* observer) {
76 connectivity_observer_list_->AddObserver(observer);
77 }
78
79 void ConnectivityChecker::RemoveConnectivityObserver(
80 ConnectivityObserver* observer) {
81 connectivity_observer_list_->RemoveObserver(observer);
82 }
83
84 bool ConnectivityChecker::Connected() const {
85 return connected_;
86 }
87
88 void ConnectivityChecker::SetConnectivity(bool connected) {
89 if (connected)
90 bad_responses_ = 0;
gunsch 2015/02/20 01:57:28 how about moving "bad_responses_ = 0" to "OnRespon
derekjchow1 2015/02/20 02:24:16 Done.
91
92 if (connected_ == connected)
93 return;
94
95 connected_ = connected;
96 connectivity_observer_list_->Notify(
97 FROM_HERE, &ConnectivityObserver::OnConnectivityChanged, connected);
98 LOG(INFO) << "Global connection is: " << (connected ? "Up" : "Down");
99 }
100
101 void ConnectivityChecker::Check() {
102 if (!loop_proxy_->BelongsToCurrentThread()) {
103 loop_proxy_->PostTask(FROM_HERE,
104 base::Bind(&ConnectivityChecker::Check, this));
105 return;
106 }
107 DCHECK(url_request_context_.get());
108
109 // If url_request_ is non-null, there is already a check going on. Don't
110 // start another.
111 if (url_request_.get())
112 return;
113
114 VLOG(2) << "Connectivity check: url=" << *connectivity_check_url_;
115 url_request_ = url_request_context_->CreateRequest(
116 *connectivity_check_url_, net::MAXIMUM_PRIORITY, this, NULL);
117 url_request_->set_method("HEAD");
118 url_request_->Start();
119 }
120
121 void ConnectivityChecker::OnConnectionTypeChanged(
122 net::NetworkChangeNotifier::ConnectionType type) {
123 Cancel();
124
125 // If there is no connection, set connectivity to false. Otherwise retest
126 // connectivity
127 if (type == net::NetworkChangeNotifier::CONNECTION_NONE) {
128 SetConnectivity(false);
129 } else {
130 Check();
131 }
132 }
133
134 void ConnectivityChecker::OnResponseStarted(net::URLRequest* request) {
135 int http_response_code =
136 (request->status().is_success() &&
137 request->response_info().headers.get() != NULL)
138 ? request->response_info().headers->response_code()
139 : net::HTTP_BAD_REQUEST;
140
141 // Clears resources.
142 url_request_.reset(NULL); // URLRequest::Cancel() is called in destructor.
143
144 if (http_response_code < 400) {
145 SetConnectivity(true);
146 return;
147 }
148
149 ++bad_responses_;
150 if (bad_responses_ > kNumBadResponses) {
151 bad_responses_ = kNumBadResponses;
152 SetConnectivity(false);
153 }
154
155 // Check again
156 if (!net::NetworkChangeNotifier::IsOffline()) {
157 loop_proxy_->PostDelayedTask(
158 FROM_HERE, base::Bind(&ConnectivityChecker::Check, this),
159 base::TimeDelta::FromSeconds(kConnectivityPeriodSeconds));
160 }
161 }
162
163 void ConnectivityChecker::OnReadCompleted(net::URLRequest* request,
164 int bytes_read) {
165 NOTREACHED();
166 }
167
168 void ConnectivityChecker::Cancel() {
169 if (url_request_.get()) {
170 VLOG(2) << "Cancel connectivity check in progress";
171 url_request_.reset(NULL); // URLRequest::Cancel() is called in destructor.
172 }
173 }
174
175 } // namespace chromecast
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698